mirror of https://gitee.com/openkylin/linux.git
Merge branch 'akpm' (Andrew's patch-bomb)
Merge misc patches from Andrew Morton: "Incoming: - lots of misc stuff - backlight tree updates - lib/ updates - Oleg's percpu-rwsem changes - checkpatch - rtc - aoe - more checkpoint/restart support I still have a pile of MM stuff pending - Pekka should be merging later today after which that is good to go. A number of other things are twiddling thumbs awaiting maintainer merges." * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (180 commits) scatterlist: don't BUG when we can trivially return a proper error. docs: update documentation about /proc/<pid>/fdinfo/<fd> fanotify output fs, fanotify: add @mflags field to fanotify output docs: add documentation about /proc/<pid>/fdinfo/<fd> output fs, notify: add procfs fdinfo helper fs, exportfs: add exportfs_encode_inode_fh() helper fs, exportfs: escape nil dereference if no s_export_op present fs, epoll: add procfs fdinfo helper fs, eventfd: add procfs fdinfo helper procfs: add ability to plug in auxiliary fdinfo providers tools/testing/selftests/kcmp/kcmp_test.c: print reason for failure in kcmp_test breakpoint selftests: print failure status instead of cause make error kcmp selftests: print fail status instead of cause make error kcmp selftests: make run_tests fix mem-hotplug selftests: print failure status instead of cause make error cpu-hotplug selftests: print failure status instead of cause make error mqueue selftests: print failure status instead of cause make error vm selftests: print failure status instead of cause make error ubifs: use prandom_bytes mtd: nandsim: use prandom_bytes ...
This commit is contained in:
commit
848b81415c
|
@ -60,7 +60,6 @@ modules.builtin
|
|||
# Generated include files
|
||||
#
|
||||
include/config
|
||||
include/linux/version.h
|
||||
include/generated
|
||||
arch/*/include/generated
|
||||
|
||||
|
|
|
@ -136,8 +136,6 @@ fault-injection/
|
|||
- dir with docs about the fault injection capabilities infrastructure.
|
||||
fb/
|
||||
- directory with info on the frame buffer graphics abstraction layer.
|
||||
feature-removal-schedule.txt
|
||||
- list of files and features that are going to be removed.
|
||||
filesystems/
|
||||
- info on the vfs and the various filesystems that Linux supports.
|
||||
firmware_class/
|
||||
|
|
|
@ -36,9 +36,6 @@ The different levels of stability are:
|
|||
the kernel, but are marked to be removed at some later point in
|
||||
time. The description of the interface will document the reason
|
||||
why it is obsolete and when it can be expected to be removed.
|
||||
The file Documentation/feature-removal-schedule.txt may describe
|
||||
some of these interfaces, giving a schedule for when they will
|
||||
be removed.
|
||||
|
||||
removed/
|
||||
This directory contains a list of the old interfaces that have
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
|
||||
<sect1><title>String Conversions</title>
|
||||
!Elib/vsprintf.c
|
||||
!Finclude/linux/kernel.h kstrtol
|
||||
!Finclude/linux/kernel.h kstrtoul
|
||||
!Elib/kstrtox.c
|
||||
</sect1>
|
||||
<sect1><title>String Manipulation</title>
|
||||
<!-- All functions are exported at now
|
||||
|
|
|
@ -125,7 +125,9 @@ DRIVER OPTIONS
|
|||
The aoe_deadsecs module parameter determines the maximum number of
|
||||
seconds that the driver will wait for an AoE device to provide a
|
||||
response to an AoE command. After aoe_deadsecs seconds have
|
||||
elapsed, the AoE device will be marked as "down".
|
||||
elapsed, the AoE device will be marked as "down". A value of zero
|
||||
is supported for testing purposes and makes the aoe driver keep
|
||||
trying AoE commands forever.
|
||||
|
||||
The aoe_maxout module parameter has a default of 128. This is the
|
||||
maximum number of unresponded packets that will be sent to an AoE
|
||||
|
|
|
@ -35,11 +35,8 @@ For supporting platform specific data, the lp855x platform data can be used.
|
|||
* 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.
|
||||
* period_ns : Platform specific PWM period value. unit is nano.
|
||||
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
|
||||
|
@ -71,8 +68,5 @@ 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,
|
||||
},
|
||||
.period_ns = 1000000,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
* i.MX25 Real Time Clock controller
|
||||
|
||||
This binding supports the following chips: i.MX25, i.MX53
|
||||
|
||||
Required properties:
|
||||
- compatible: should be: "fsl,imx25-rtc"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- interrupts: rtc alarm interrupt
|
||||
|
||||
Example:
|
||||
|
||||
rtc@80056000 {
|
||||
compatible = "fsl,imx53-rtc", "fsl,imx25-rtc";
|
||||
reg = <0x80056000 2000>;
|
||||
interrupts = <29>;
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
TI Real Time Clock
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,da830-rtc"
|
||||
- reg: Address range of rtc register set
|
||||
- interrupts: rtc timer, alarm interrupts in order
|
||||
- interrupt-parent: phandle for the interrupt controller
|
||||
|
||||
Example:
|
||||
|
||||
rtc@1c23000 {
|
||||
compatible = "ti,da830-rtc";
|
||||
reg = <0x23000 0x1000>;
|
||||
interrupts = <19
|
||||
19>;
|
||||
interrupt-parent = <&intc>;
|
||||
};
|
|
@ -41,6 +41,7 @@ Table of Contents
|
|||
3.5 /proc/<pid>/mountinfo - Information about mounts
|
||||
3.6 /proc/<pid>/comm & /proc/<pid>/task/<tid>/comm
|
||||
3.7 /proc/<pid>/task/<tid>/children - Information about task children
|
||||
3.8 /proc/<pid>/fdinfo/<fd> - Information about opened file
|
||||
|
||||
4 Configuring procfs
|
||||
4.1 Mount options
|
||||
|
@ -142,7 +143,7 @@ Table 1-1: Process specific entries in /proc
|
|||
pagemap Page table
|
||||
stack Report full stack trace, enable via CONFIG_STACKTRACE
|
||||
smaps a extension based on maps, showing the memory consumption of
|
||||
each mapping
|
||||
each mapping and flags associated with it
|
||||
..............................................................................
|
||||
|
||||
For example, to get the status information of a process, all you have to do is
|
||||
|
@ -181,6 +182,7 @@ read the file /proc/PID/status:
|
|||
CapPrm: 0000000000000000
|
||||
CapEff: 0000000000000000
|
||||
CapBnd: ffffffffffffffff
|
||||
Seccomp: 0
|
||||
voluntary_ctxt_switches: 0
|
||||
nonvoluntary_ctxt_switches: 1
|
||||
|
||||
|
@ -237,6 +239,7 @@ Table 1-2: Contents of the status files (as of 2.6.30-rc7)
|
|||
CapPrm bitmap of permitted capabilities
|
||||
CapEff bitmap of effective capabilities
|
||||
CapBnd bitmap of capabilities bounding set
|
||||
Seccomp seccomp mode, like prctl(PR_GET_SECCOMP, ...)
|
||||
Cpus_allowed mask of CPUs on which this process may run
|
||||
Cpus_allowed_list Same as previous, but in "list format"
|
||||
Mems_allowed mask of memory nodes allowed to this process
|
||||
|
@ -415,8 +418,9 @@ Swap: 0 kB
|
|||
KernelPageSize: 4 kB
|
||||
MMUPageSize: 4 kB
|
||||
Locked: 374 kB
|
||||
VmFlags: rd ex mr mw me de
|
||||
|
||||
The first of these lines shows the same information as is displayed for the
|
||||
the first of these lines shows the same information as is displayed for the
|
||||
mapping in /proc/PID/maps. The remaining lines show the size of the mapping
|
||||
(size), the amount of the mapping that is currently resident in RAM (RSS), the
|
||||
process' proportional share of this mapping (PSS), the number of clean and
|
||||
|
@ -430,6 +434,41 @@ and a page is modified, the file page is replaced by a private anonymous copy.
|
|||
"Swap" shows how much would-be-anonymous memory is also used, but out on
|
||||
swap.
|
||||
|
||||
"VmFlags" field deserves a separate description. This member represents the kernel
|
||||
flags associated with the particular virtual memory area in two letter encoded
|
||||
manner. The codes are the following:
|
||||
rd - readable
|
||||
wr - writeable
|
||||
ex - executable
|
||||
sh - shared
|
||||
mr - may read
|
||||
mw - may write
|
||||
me - may execute
|
||||
ms - may share
|
||||
gd - stack segment growns down
|
||||
pf - pure PFN range
|
||||
dw - disabled write to the mapped file
|
||||
lo - pages are locked in memory
|
||||
io - memory mapped I/O area
|
||||
sr - sequential read advise provided
|
||||
rr - random read advise provided
|
||||
dc - do not copy area on fork
|
||||
de - do not expand area on remapping
|
||||
ac - area is accountable
|
||||
nr - swap space is not reserved for the area
|
||||
ht - area uses huge tlb pages
|
||||
nl - non-linear mapping
|
||||
ar - architecture specific flag
|
||||
dd - do not include area into core dump
|
||||
mm - mixed map area
|
||||
hg - huge page advise flag
|
||||
nh - no-huge page advise flag
|
||||
mg - mergable advise flag
|
||||
|
||||
Note that there is no guarantee that every flag and associated mnemonic will
|
||||
be present in all further kernel releases. Things get changed, the flags may
|
||||
be vanished or the reverse -- new added.
|
||||
|
||||
This file is only present if the CONFIG_MMU kernel configuration option is
|
||||
enabled.
|
||||
|
||||
|
@ -1595,6 +1634,93 @@ pids, so one need to either stop or freeze processes being inspected
|
|||
if precise results are needed.
|
||||
|
||||
|
||||
3.7 /proc/<pid>/fdinfo/<fd> - Information about opened file
|
||||
---------------------------------------------------------------
|
||||
This file provides information associated with an opened file. The regular
|
||||
files have at least two fields -- 'pos' and 'flags'. The 'pos' represents
|
||||
the current offset of the opened file in decimal form [see lseek(2) for
|
||||
details] and 'flags' denotes the octal O_xxx mask the file has been
|
||||
created with [see open(2) for details].
|
||||
|
||||
A typical output is
|
||||
|
||||
pos: 0
|
||||
flags: 0100002
|
||||
|
||||
The files such as eventfd, fsnotify, signalfd, epoll among the regular pos/flags
|
||||
pair provide additional information particular to the objects they represent.
|
||||
|
||||
Eventfd files
|
||||
~~~~~~~~~~~~~
|
||||
pos: 0
|
||||
flags: 04002
|
||||
eventfd-count: 5a
|
||||
|
||||
where 'eventfd-count' is hex value of a counter.
|
||||
|
||||
Signalfd files
|
||||
~~~~~~~~~~~~~~
|
||||
pos: 0
|
||||
flags: 04002
|
||||
sigmask: 0000000000000200
|
||||
|
||||
where 'sigmask' is hex value of the signal mask associated
|
||||
with a file.
|
||||
|
||||
Epoll files
|
||||
~~~~~~~~~~~
|
||||
pos: 0
|
||||
flags: 02
|
||||
tfd: 5 events: 1d data: ffffffffffffffff
|
||||
|
||||
where 'tfd' is a target file descriptor number in decimal form,
|
||||
'events' is events mask being watched and the 'data' is data
|
||||
associated with a target [see epoll(7) for more details].
|
||||
|
||||
Fsnotify files
|
||||
~~~~~~~~~~~~~~
|
||||
For inotify files the format is the following
|
||||
|
||||
pos: 0
|
||||
flags: 02000000
|
||||
inotify wd:3 ino:9e7e sdev:800013 mask:800afce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:7e9e0000640d1b6d
|
||||
|
||||
where 'wd' is a watch descriptor in decimal form, ie a target file
|
||||
descriptor number, 'ino' and 'sdev' are inode and device where the
|
||||
target file resides and the 'mask' is the mask of events, all in hex
|
||||
form [see inotify(7) for more details].
|
||||
|
||||
If the kernel was built with exportfs support, the path to the target
|
||||
file is encoded as a file handle. The file handle is provided by three
|
||||
fields 'fhandle-bytes', 'fhandle-type' and 'f_handle', all in hex
|
||||
format.
|
||||
|
||||
If the kernel is built without exportfs support the file handle won't be
|
||||
printed out.
|
||||
|
||||
If there is no inotify mark attached yet the 'inotify' line will be omitted.
|
||||
|
||||
For fanotify files the format is
|
||||
|
||||
pos: 0
|
||||
flags: 02
|
||||
fanotify flags:10 event-flags:0
|
||||
fanotify mnt_id:12 mflags:40 mask:38 ignored_mask:40000003
|
||||
fanotify ino:4f969 sdev:800013 mflags:0 mask:3b ignored_mask:40000000 fhandle-bytes:8 fhandle-type:1 f_handle:69f90400c275b5b4
|
||||
|
||||
where fanotify 'flags' and 'event-flags' are values used in fanotify_init
|
||||
call, 'mnt_id' is the mount point identifier, 'mflags' is the value of
|
||||
flags associated with mark which are tracked separately from events
|
||||
mask. 'ino', 'sdev' are target inode and device, 'mask' is the events
|
||||
mask and 'ignored_mask' is the mask of events which are to be ignored.
|
||||
All in hex format. Incorporation of 'mflags', 'mask' and 'ignored_mask'
|
||||
does provide information about flags and mask used in fanotify_mark
|
||||
call [see fsnotify manpage for details].
|
||||
|
||||
While the first three lines are mandatory and always printed, the rest is
|
||||
optional and may be omitted if no marks created yet.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Configuring procfs
|
||||
------------------------------------------------------------------------------
|
||||
|
|
|
@ -111,6 +111,15 @@ tz=UTC -- Interpret timestamps as UTC rather than local time.
|
|||
useful when mounting devices (like digital cameras)
|
||||
that are set to UTC in order to avoid the pitfalls of
|
||||
local time.
|
||||
time_offset=minutes
|
||||
-- Set offset for conversion of timestamps from local time
|
||||
used by FAT to UTC. I.e. <minutes> minutes will be subtracted
|
||||
from each timestamp to convert it to UTC used internally by
|
||||
Linux. This is useful when time zone set in sys_tz is
|
||||
not the time zone used by the filesystem. Note that this
|
||||
option still does not provide correct time stamps in all
|
||||
cases in presence of DST - time stamps in a different DST
|
||||
setting will be off by one hour.
|
||||
|
||||
showexec -- If set, the execute permission bits of the file will be
|
||||
allowed only if the extension part of the name is .EXE,
|
||||
|
|
|
@ -1503,9 +1503,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
mem=nn[KMG] [KNL,BOOT] Force usage of a specific amount of memory
|
||||
Amount of memory to be used when the kernel is not able
|
||||
to see the whole system memory or for test.
|
||||
[X86-32] Use together with memmap= to avoid physical
|
||||
address space collisions. Without memmap= PCI devices
|
||||
could be placed at addresses belonging to unused RAM.
|
||||
[X86] Work as limiting max address. Use together
|
||||
with memmap= to avoid physical address space collisions.
|
||||
Without memmap= PCI devices could be placed at addresses
|
||||
belonging to unused RAM.
|
||||
|
||||
mem=nopentium [BUGS=X86-32] Disable usage of 4MB pages for kernel
|
||||
memory.
|
||||
|
|
|
@ -12,6 +12,8 @@ apparmor.txt
|
|||
- documentation on the AppArmor security extension.
|
||||
credentials.txt
|
||||
- documentation about credentials in Linux.
|
||||
keys-ecryptfs.txt
|
||||
- description of the encryption keys for the ecryptfs filesystem.
|
||||
keys-request-key.txt
|
||||
- description of the kernel key request service.
|
||||
keys-trusted-encrypted.txt
|
||||
|
|
|
@ -49,6 +49,24 @@ be generated without __CHECK_ENDIAN__.
|
|||
__bitwise - noisy stuff; in particular, __le*/__be* are that. We really
|
||||
don't want to drown in noise unless we'd explicitly asked for it.
|
||||
|
||||
Using sparse for lock checking
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following macros are undefined for gcc and defined during a sparse
|
||||
run to use the "context" tracking feature of sparse, applied to
|
||||
locking. These annotations tell sparse when a lock is held, with
|
||||
regard to the annotated function's entry and exit.
|
||||
|
||||
__must_hold - The specified lock is held on function entry and exit.
|
||||
|
||||
__acquires - The specified lock is held on function exit, but not entry.
|
||||
|
||||
__releases - The specified lock is held on function entry, but not exit.
|
||||
|
||||
If the function enters and exits without the lock held, acquiring and
|
||||
releasing the lock inside the function in a balanced way, no
|
||||
annotation is needed. The tree annotations above are for cases where
|
||||
sparse would otherwise report a context imbalance.
|
||||
|
||||
Getting sparse
|
||||
~~~~~~~~~~~~~~
|
||||
|
|
18
MAINTAINERS
18
MAINTAINERS
|
@ -1280,7 +1280,7 @@ F: Documentation/hwmon/asc7621
|
|||
F: drivers/hwmon/asc7621.c
|
||||
|
||||
ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS
|
||||
M: Corentin Chary <corentincj@iksaif.net>
|
||||
M: Corentin Chary <corentin.chary@gmail.com>
|
||||
L: acpi4asus-user@lists.sourceforge.net
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
W: http://acpi4asus.sf.net
|
||||
|
@ -1929,7 +1929,7 @@ F: scripts/checkpatch.pl
|
|||
|
||||
CHINESE DOCUMENTATION
|
||||
M: Harry Wei <harryxiyou@gmail.com>
|
||||
L: xiyoulinuxkernelgroup@googlegroups.com
|
||||
L: xiyoulinuxkernelgroup@googlegroups.com (subscribers-only)
|
||||
L: linux-kernel@zh-kernel.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/zh_CN/
|
||||
|
@ -2982,7 +2982,6 @@ L: linux-ext4@vger.kernel.org
|
|||
S: Maintained
|
||||
F: Documentation/filesystems/ext3.txt
|
||||
F: fs/ext3/
|
||||
F: include/linux/ext3*
|
||||
|
||||
EXT4 FILE SYSTEM
|
||||
M: "Theodore Ts'o" <tytso@mit.edu>
|
||||
|
@ -3129,7 +3128,8 @@ W: http://ieee1394.wiki.kernel.org/
|
|||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git
|
||||
S: Maintained
|
||||
F: drivers/firewire/
|
||||
F: include/linux/firewire*.h
|
||||
F: include/linux/firewire.h
|
||||
F: include/uapi/linux/firewire*.h
|
||||
F: tools/firewire/
|
||||
|
||||
FIRMWARE LOADER (request_firmware)
|
||||
|
@ -4314,7 +4314,6 @@ M: Jan Kara <jack@suse.cz>
|
|||
L: linux-ext4@vger.kernel.org
|
||||
S: Maintained
|
||||
F: fs/jbd/
|
||||
F: include/linux/ext3_jbd.h
|
||||
F: include/linux/jbd.h
|
||||
|
||||
JOURNALLING LAYER FOR BLOCK DEVICES (JBD2)
|
||||
|
@ -6492,7 +6491,7 @@ F: drivers/media/pci/saa7146/
|
|||
F: include/media/saa7146*
|
||||
|
||||
SAMSUNG LAPTOP DRIVER
|
||||
M: Corentin Chary <corentincj@iksaif.net>
|
||||
M: Corentin Chary <corentin.chary@gmail.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/samsung-laptop.c
|
||||
|
@ -7546,6 +7545,13 @@ S: Maintained
|
|||
F: sound/soc/codecs/lm49453*
|
||||
F: sound/soc/codecs/isabelle*
|
||||
|
||||
TI LP855x BACKLIGHT DRIVER
|
||||
M: Milo Kim <milo.kim@ti.com>
|
||||
S: Maintained
|
||||
F: Documentation/backlight/lp855x-driver.txt
|
||||
F: drivers/video/backlight/lp855x_bl.c
|
||||
F: include/linux/platform_data/lp855x.h
|
||||
|
||||
TI TWL4030 SERIES SOC CODEC DRIVER
|
||||
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
|
|
|
@ -80,6 +80,7 @@ config UPROBES
|
|||
bool "Transparent user-space probes (EXPERIMENTAL)"
|
||||
depends on UPROBE_EVENT && PERF_EVENTS
|
||||
default n
|
||||
select PERCPU_RWSEM
|
||||
help
|
||||
Uprobes is the user-space counterpart to kprobes: they
|
||||
enable instrumentation applications (such as 'perf probe')
|
||||
|
|
|
@ -725,7 +725,7 @@ static struct resource da8xx_rtc_resources[] = {
|
|||
};
|
||||
|
||||
static struct platform_device da8xx_rtc_device = {
|
||||
.name = "omap_rtc",
|
||||
.name = "da830-rtc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(da8xx_rtc_resources),
|
||||
.resource = da8xx_rtc_resources,
|
||||
|
@ -734,17 +734,6 @@ static struct platform_device da8xx_rtc_device = {
|
|||
int da8xx_register_rtc(void)
|
||||
{
|
||||
int ret;
|
||||
void __iomem *base;
|
||||
|
||||
base = ioremap(DA8XX_RTC_BASE, SZ_4K);
|
||||
if (WARN_ON(!base))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Unlock the rtc's registers */
|
||||
__raw_writel(0x83e70b13, base + 0x6c);
|
||||
__raw_writel(0x95a4f1e0, base + 0x70);
|
||||
|
||||
iounmap(base);
|
||||
|
||||
ret = platform_device_register(&da8xx_rtc_device);
|
||||
if (!ret)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define __ARCH_WANT_SYS_GETPGRP
|
||||
#define __ARCH_WANT_SYS_LLSEEK
|
||||
#define __ARCH_WANT_SYS_NICE
|
||||
#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
|
||||
#define __ARCH_WANT_SYS_SIGPENDING
|
||||
#define __ARCH_WANT_SYS_SIGPROCMASK
|
||||
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
|
||||
|
|
|
@ -28,21 +28,6 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/unistd32.h>
|
||||
|
||||
asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
|
||||
struct compat_timespec __user *interval)
|
||||
{
|
||||
struct timespec t;
|
||||
int ret;
|
||||
mm_segment_t old_fs = get_fs();
|
||||
|
||||
set_fs(KERNEL_DS);
|
||||
ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
|
||||
set_fs(old_fs);
|
||||
if (put_compat_timespec(&t, interval))
|
||||
return -EFAULT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
do_compat_cache_op(unsigned long start, unsigned long end, int flags)
|
||||
{
|
||||
|
|
|
@ -804,9 +804,9 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
BUG_ON(memory_start == memory_end);
|
||||
|
||||
init_mm.start_code = (unsigned long) &_stext;
|
||||
init_mm.end_code = (unsigned long) &_etext;
|
||||
init_mm.end_data = (unsigned long) &_edata;
|
||||
init_mm.start_code = (unsigned long) _stext;
|
||||
init_mm.end_code = (unsigned long) _etext;
|
||||
init_mm.end_data = (unsigned long) _edata;
|
||||
#if 0 /* DAVIDM - don't set brk just incase someone decides to use it */
|
||||
init_mm.brk = (unsigned long) &_end;
|
||||
#else
|
||||
|
@ -814,10 +814,8 @@ void __init setup_arch(char **cmdline_p)
|
|||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x BSS=0x%06x-0x%06x\n",
|
||||
(int) &_stext, (int) &_etext,
|
||||
(int) &_sdata, (int) &_edata,
|
||||
(int) &_sbss, (int) &_ebss);
|
||||
printk("KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p BSS=0x%p-0x%p\n",
|
||||
_stext, _etext, _sdata, _edata, __bss_start, __bss_stop);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VT
|
||||
|
|
|
@ -146,7 +146,7 @@ void __init mem_init(void)
|
|||
|
||||
#else
|
||||
codek = (_etext - _stext) >> 10;
|
||||
datak = 0; //(_ebss - _sdata) >> 10;
|
||||
datak = 0; //(__bss_stop - _sdata) >> 10;
|
||||
#endif
|
||||
|
||||
tmp = nr_free_pages() << PAGE_SHIFT;
|
||||
|
|
|
@ -320,28 +320,28 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal)
|
|||
ppc_md.log_error(buf, err_type, fatal);
|
||||
}
|
||||
|
||||
#define __define_machine_initcall(mach,level,fn,id) \
|
||||
#define __define_machine_initcall(mach, fn, id) \
|
||||
static int __init __machine_initcall_##mach##_##fn(void) { \
|
||||
if (machine_is(mach)) return fn(); \
|
||||
return 0; \
|
||||
} \
|
||||
__define_initcall(level,__machine_initcall_##mach##_##fn,id);
|
||||
__define_initcall(__machine_initcall_##mach##_##fn, id);
|
||||
|
||||
#define machine_core_initcall(mach,fn) __define_machine_initcall(mach,"1",fn,1)
|
||||
#define machine_core_initcall_sync(mach,fn) __define_machine_initcall(mach,"1s",fn,1s)
|
||||
#define machine_postcore_initcall(mach,fn) __define_machine_initcall(mach,"2",fn,2)
|
||||
#define machine_postcore_initcall_sync(mach,fn) __define_machine_initcall(mach,"2s",fn,2s)
|
||||
#define machine_arch_initcall(mach,fn) __define_machine_initcall(mach,"3",fn,3)
|
||||
#define machine_arch_initcall_sync(mach,fn) __define_machine_initcall(mach,"3s",fn,3s)
|
||||
#define machine_subsys_initcall(mach,fn) __define_machine_initcall(mach,"4",fn,4)
|
||||
#define machine_subsys_initcall_sync(mach,fn) __define_machine_initcall(mach,"4s",fn,4s)
|
||||
#define machine_fs_initcall(mach,fn) __define_machine_initcall(mach,"5",fn,5)
|
||||
#define machine_fs_initcall_sync(mach,fn) __define_machine_initcall(mach,"5s",fn,5s)
|
||||
#define machine_rootfs_initcall(mach,fn) __define_machine_initcall(mach,"rootfs",fn,rootfs)
|
||||
#define machine_device_initcall(mach,fn) __define_machine_initcall(mach,"6",fn,6)
|
||||
#define machine_device_initcall_sync(mach,fn) __define_machine_initcall(mach,"6s",fn,6s)
|
||||
#define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7)
|
||||
#define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s)
|
||||
#define machine_core_initcall(mach, fn) __define_machine_initcall(mach, fn, 1)
|
||||
#define machine_core_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 1s)
|
||||
#define machine_postcore_initcall(mach, fn) __define_machine_initcall(mach, fn, 2)
|
||||
#define machine_postcore_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 2s)
|
||||
#define machine_arch_initcall(mach, fn) __define_machine_initcall(mach, fn, 3)
|
||||
#define machine_arch_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 3s)
|
||||
#define machine_subsys_initcall(mach, fn) __define_machine_initcall(mach, fn, 4)
|
||||
#define machine_subsys_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 4s)
|
||||
#define machine_fs_initcall(mach, fn) __define_machine_initcall(mach, fn, 5)
|
||||
#define machine_fs_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 5s)
|
||||
#define machine_rootfs_initcall(mach, fn) __define_machine_initcall(mach, fn, rootfs)
|
||||
#define machine_device_initcall(mach, fn) __define_machine_initcall(mach, fn, 6)
|
||||
#define machine_device_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 6s)
|
||||
#define machine_late_initcall(mach, fn) __define_machine_initcall(mach, fn, 7)
|
||||
#define machine_late_initcall_sync(mach, fn) __define_machine_initcall(mach, fn, 7s)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_POWERPC_MACHDEP_H */
|
||||
|
|
|
@ -164,7 +164,7 @@ COMPAT_SYS_SPU(sched_getscheduler)
|
|||
SYSCALL_SPU(sched_yield)
|
||||
COMPAT_SYS_SPU(sched_get_priority_max)
|
||||
COMPAT_SYS_SPU(sched_get_priority_min)
|
||||
COMPAT_SYS_SPU(sched_rr_get_interval)
|
||||
SYSX_SPU(sys_sched_rr_get_interval,compat_sys_sched_rr_get_interval_wrapper,sys_sched_rr_get_interval)
|
||||
COMPAT_SYS_SPU(nanosleep)
|
||||
SYSCALL_SPU(mremap)
|
||||
SYSCALL_SPU(setresuid)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
|
||||
#define __ARCH_WANT_SYS_NEWFSTATAT
|
||||
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
||||
#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
|
||||
#endif
|
||||
#define __ARCH_WANT_SYS_EXECVE
|
||||
#define __ARCH_WANT_SYS_FORK
|
||||
|
|
|
@ -175,19 +175,10 @@ asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 a
|
|||
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
|
||||
* and the register representation of a signed int (msr in 64-bit mode) is performed.
|
||||
*/
|
||||
asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval)
|
||||
asmlinkage long compat_sys_sched_rr_get_interval_wrapper(u32 pid,
|
||||
struct compat_timespec __user *interval)
|
||||
{
|
||||
struct timespec t;
|
||||
int ret;
|
||||
mm_segment_t old_fs = get_fs ();
|
||||
|
||||
/* The __user pointer cast is valid because of the set_fs() */
|
||||
set_fs (KERNEL_DS);
|
||||
ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t);
|
||||
set_fs (old_fs);
|
||||
if (put_compat_timespec(&t, interval))
|
||||
return -EFAULT;
|
||||
return ret;
|
||||
return compat_sys_sched_rr_get_interval((int)pid, interval);
|
||||
}
|
||||
|
||||
/* Note: it is necessary to treat mode as an unsigned int,
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#define __ARCH_WANT_COMPAT_SYS_TIME
|
||||
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
|
||||
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
||||
#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
|
||||
#endif
|
||||
#define __ARCH_WANT_SYS_EXECVE
|
||||
|
||||
|
|
|
@ -211,20 +211,6 @@ asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
|
|||
return sys_sysfs(option, arg1, arg2);
|
||||
}
|
||||
|
||||
asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval)
|
||||
{
|
||||
struct timespec t;
|
||||
int ret;
|
||||
mm_segment_t old_fs = get_fs ();
|
||||
|
||||
set_fs (KERNEL_DS);
|
||||
ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
|
||||
set_fs (old_fs);
|
||||
if (put_compat_timespec(&t, interval))
|
||||
return -EFAULT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage long compat_sys_rt_sigprocmask(int how,
|
||||
compat_sigset_t __user *set,
|
||||
compat_sigset_t __user *oset,
|
||||
|
|
|
@ -296,8 +296,6 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags,
|
|||
long compat_sys_fallocate(int fd, int mode,
|
||||
u32 offset_lo, u32 offset_hi,
|
||||
u32 len_lo, u32 len_hi);
|
||||
long compat_sys_sched_rr_get_interval(compat_pid_t pid,
|
||||
struct compat_timespec __user *interval);
|
||||
|
||||
/* Assembly trampoline to avoid clobbering r0. */
|
||||
long _compat_sys_rt_sigreturn(void);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
/* In compat mode, we use sys_llseek() for compat_sys_llseek(). */
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define __ARCH_WANT_SYS_LLSEEK
|
||||
#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
|
||||
#endif
|
||||
#define __ARCH_WANT_SYS_NEWFSTATAT
|
||||
#define __ARCH_WANT_SYS_EXECVE
|
||||
|
|
|
@ -76,24 +76,6 @@ long compat_sys_fallocate(int fd, int mode,
|
|||
((loff_t)len_hi << 32) | len_lo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
long compat_sys_sched_rr_get_interval(compat_pid_t pid,
|
||||
struct compat_timespec __user *interval)
|
||||
{
|
||||
struct timespec t;
|
||||
int ret;
|
||||
mm_segment_t old_fs = get_fs();
|
||||
|
||||
set_fs(KERNEL_DS);
|
||||
ret = sys_sched_rr_get_interval(pid,
|
||||
(struct timespec __force __user *)&t);
|
||||
set_fs(old_fs);
|
||||
if (put_compat_timespec(&t, interval))
|
||||
return -EFAULT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Provide the compat syscall number to call mapping. */
|
||||
#undef __SYSCALL
|
||||
#define __SYSCALL(nr, call) [nr] = (call),
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/* */
|
|
@ -0,0 +1 @@
|
|||
/* */
|
|
@ -4,6 +4,7 @@
|
|||
menuconfig BLOCK
|
||||
bool "Enable the block layer" if EXPERT
|
||||
default y
|
||||
select PERCPU_RWSEM
|
||||
help
|
||||
Provide block layer support for the kernel.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
|
||||
#define VERSION "50"
|
||||
#define VERSION "81"
|
||||
#define AOE_MAJOR 152
|
||||
#define DEVICE_NAME "aoe"
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
|||
#define AOE_PARTITIONS (16)
|
||||
#endif
|
||||
|
||||
#define WHITESPACE " \t\v\f\n"
|
||||
#define WHITESPACE " \t\v\f\n,"
|
||||
|
||||
enum {
|
||||
AOECMD_ATA,
|
||||
|
@ -73,21 +73,29 @@ enum {
|
|||
DEVFL_TKILL = (1<<1), /* flag for timer to know when to kill self */
|
||||
DEVFL_EXT = (1<<2), /* device accepts lba48 commands */
|
||||
DEVFL_GDALLOC = (1<<3), /* need to alloc gendisk */
|
||||
DEVFL_KICKME = (1<<4), /* slow polling network card catch */
|
||||
DEVFL_NEWSIZE = (1<<5), /* need to update dev size in block layer */
|
||||
DEVFL_GD_NOW = (1<<4), /* allocating gendisk */
|
||||
DEVFL_KICKME = (1<<5), /* slow polling network card catch */
|
||||
DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */
|
||||
DEVFL_FREEING = (1<<7), /* set when device is being cleaned up */
|
||||
DEVFL_FREED = (1<<8), /* device has been cleaned up */
|
||||
};
|
||||
|
||||
enum {
|
||||
DEFAULTBCNT = 2 * 512, /* 2 sectors */
|
||||
MIN_BUFS = 16,
|
||||
NTARGETS = 8,
|
||||
NTARGETS = 4,
|
||||
NAOEIFS = 8,
|
||||
NSKBPOOLMAX = 256,
|
||||
NFACTIVE = 61,
|
||||
|
||||
TIMERTICK = HZ / 10,
|
||||
MINTIMER = HZ >> 2,
|
||||
MAXTIMER = HZ << 1,
|
||||
RTTSCALE = 8,
|
||||
RTTDSCALE = 3,
|
||||
RTTAVG_INIT = USEC_PER_SEC / 4 << RTTSCALE,
|
||||
RTTDEV_INIT = RTTAVG_INIT / 4,
|
||||
|
||||
HARD_SCORN_SECS = 10, /* try another remote port after this */
|
||||
MAX_TAINT = 1000, /* cap on aoetgt taint */
|
||||
};
|
||||
|
||||
struct buf {
|
||||
|
@ -100,10 +108,17 @@ struct buf {
|
|||
struct request *rq;
|
||||
};
|
||||
|
||||
enum frame_flags {
|
||||
FFL_PROBE = 1,
|
||||
};
|
||||
|
||||
struct frame {
|
||||
struct list_head head;
|
||||
u32 tag;
|
||||
struct timeval sent; /* high-res time packet was sent */
|
||||
u32 sent_jiffs; /* low-res jiffies-based sent time */
|
||||
ulong waited;
|
||||
ulong waited_total;
|
||||
struct aoetgt *t; /* parent target I belong to */
|
||||
sector_t lba;
|
||||
struct sk_buff *skb; /* command skb freed on module exit */
|
||||
|
@ -112,6 +127,7 @@ struct frame {
|
|||
struct bio_vec *bv;
|
||||
ulong bcnt;
|
||||
ulong bv_off;
|
||||
char flags;
|
||||
};
|
||||
|
||||
struct aoeif {
|
||||
|
@ -122,28 +138,31 @@ struct aoeif {
|
|||
|
||||
struct aoetgt {
|
||||
unsigned char addr[6];
|
||||
ushort nframes;
|
||||
ushort nframes; /* cap on frames to use */
|
||||
struct aoedev *d; /* parent device I belong to */
|
||||
struct list_head ffree; /* list of free frames */
|
||||
struct aoeif ifs[NAOEIFS];
|
||||
struct aoeif *ifp; /* current aoeif in use */
|
||||
ushort nout;
|
||||
ushort maxout;
|
||||
ulong falloc;
|
||||
ulong lastwadj; /* last window adjustment */
|
||||
ushort nout; /* number of AoE commands outstanding */
|
||||
ushort maxout; /* current value for max outstanding */
|
||||
ushort next_cwnd; /* incr maxout after decrementing to zero */
|
||||
ushort ssthresh; /* slow start threshold */
|
||||
ulong falloc; /* number of allocated frames */
|
||||
int taint; /* how much we want to avoid this aoetgt */
|
||||
int minbcnt;
|
||||
int wpkts, rpkts;
|
||||
char nout_probes;
|
||||
};
|
||||
|
||||
struct aoedev {
|
||||
struct aoedev *next;
|
||||
ulong sysminor;
|
||||
ulong aoemajor;
|
||||
u32 rttavg; /* scaled AoE round trip time average */
|
||||
u32 rttdev; /* scaled round trip time mean deviation */
|
||||
u16 aoeminor;
|
||||
u16 flags;
|
||||
u16 nopen; /* (bd_openers isn't available without sleeping) */
|
||||
u16 rttavg; /* round trip average of requests/responses */
|
||||
u16 mintimer;
|
||||
u16 fw_ver; /* version of blade's firmware */
|
||||
u16 lasttag; /* last tag sent */
|
||||
u16 useme;
|
||||
|
@ -151,7 +170,7 @@ struct aoedev {
|
|||
struct work_struct work;/* disk create work struct */
|
||||
struct gendisk *gd;
|
||||
struct request_queue *blkq;
|
||||
struct hd_geometry geo;
|
||||
struct hd_geometry geo;
|
||||
sector_t ssize;
|
||||
struct timer_list timer;
|
||||
spinlock_t lock;
|
||||
|
@ -164,11 +183,12 @@ struct aoedev {
|
|||
} ip;
|
||||
ulong maxbcnt;
|
||||
struct list_head factive[NFACTIVE]; /* hash of active frames */
|
||||
struct aoetgt *targets[NTARGETS];
|
||||
struct list_head rexmitq; /* deferred retransmissions */
|
||||
struct aoetgt **targets;
|
||||
ulong ntargets; /* number of allocated aoetgt pointers */
|
||||
struct aoetgt **tgt; /* target in use when working */
|
||||
struct aoetgt *htgt; /* target needing rexmit assistance */
|
||||
ulong ntargets;
|
||||
ulong kicked;
|
||||
char ident[512];
|
||||
};
|
||||
|
||||
/* kthread tracking */
|
||||
|
@ -195,6 +215,7 @@ void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
|
|||
struct sk_buff *aoecmd_ata_rsp(struct sk_buff *);
|
||||
void aoecmd_cfg_rsp(struct sk_buff *);
|
||||
void aoecmd_sleepwork(struct work_struct *);
|
||||
void aoecmd_wreset(struct aoetgt *t);
|
||||
void aoecmd_cleanslate(struct aoedev *);
|
||||
void aoecmd_exit(void);
|
||||
int aoecmd_init(void);
|
||||
|
|
|
@ -16,11 +16,19 @@
|
|||
#include <linux/netdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <scsi/sg.h>
|
||||
#include "aoe.h"
|
||||
|
||||
static DEFINE_MUTEX(aoeblk_mutex);
|
||||
static struct kmem_cache *buf_pool_cache;
|
||||
|
||||
/* GPFS needs a larger value than the default. */
|
||||
static int aoe_maxsectors;
|
||||
module_param(aoe_maxsectors, int, 0644);
|
||||
MODULE_PARM_DESC(aoe_maxsectors,
|
||||
"When nonzero, set the maximum number of sectors per I/O request");
|
||||
|
||||
static ssize_t aoedisk_show_state(struct device *dev,
|
||||
struct device_attribute *attr, char *page)
|
||||
{
|
||||
|
@ -59,7 +67,7 @@ static ssize_t aoedisk_show_netif(struct device *dev,
|
|||
nd = nds;
|
||||
ne = nd + ARRAY_SIZE(nds);
|
||||
t = d->targets;
|
||||
te = t + NTARGETS;
|
||||
te = t + d->ntargets;
|
||||
for (; t < te && *t; t++) {
|
||||
ifp = (*t)->ifs;
|
||||
e = ifp + NAOEIFS;
|
||||
|
@ -91,6 +99,14 @@ static ssize_t aoedisk_show_fwver(struct device *dev,
|
|||
|
||||
return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver);
|
||||
}
|
||||
static ssize_t aoedisk_show_payload(struct device *dev,
|
||||
struct device_attribute *attr, char *page)
|
||||
{
|
||||
struct gendisk *disk = dev_to_disk(dev);
|
||||
struct aoedev *d = disk->private_data;
|
||||
|
||||
return snprintf(page, PAGE_SIZE, "%lu\n", d->maxbcnt);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL);
|
||||
static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL);
|
||||
|
@ -99,12 +115,14 @@ static struct device_attribute dev_attr_firmware_version = {
|
|||
.attr = { .name = "firmware-version", .mode = S_IRUGO },
|
||||
.show = aoedisk_show_fwver,
|
||||
};
|
||||
static DEVICE_ATTR(payload, S_IRUGO, aoedisk_show_payload, NULL);
|
||||
|
||||
static struct attribute *aoe_attrs[] = {
|
||||
&dev_attr_state.attr,
|
||||
&dev_attr_mac.attr,
|
||||
&dev_attr_netif.attr,
|
||||
&dev_attr_firmware_version.attr,
|
||||
&dev_attr_payload.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -129,9 +147,18 @@ aoeblk_open(struct block_device *bdev, fmode_t mode)
|
|||
struct aoedev *d = bdev->bd_disk->private_data;
|
||||
ulong flags;
|
||||
|
||||
if (!virt_addr_valid(d)) {
|
||||
pr_crit("aoe: invalid device pointer in %s\n",
|
||||
__func__);
|
||||
WARN_ON(1);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!(d->flags & DEVFL_UP) || d->flags & DEVFL_TKILL)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&aoeblk_mutex);
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
if (d->flags & DEVFL_UP) {
|
||||
if (d->flags & DEVFL_UP && !(d->flags & DEVFL_TKILL)) {
|
||||
d->nopen++;
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
mutex_unlock(&aoeblk_mutex);
|
||||
|
@ -195,9 +222,38 @@ aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
aoeblk_ioctl(struct block_device *bdev, fmode_t mode, uint cmd, ulong arg)
|
||||
{
|
||||
struct aoedev *d;
|
||||
|
||||
if (!arg)
|
||||
return -EINVAL;
|
||||
|
||||
d = bdev->bd_disk->private_data;
|
||||
if ((d->flags & DEVFL_UP) == 0) {
|
||||
pr_err("aoe: disk not up\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (cmd == HDIO_GET_IDENTITY) {
|
||||
if (!copy_to_user((void __user *) arg, &d->ident,
|
||||
sizeof(d->ident)))
|
||||
return 0;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* udev calls scsi_id, which uses SG_IO, resulting in noise */
|
||||
if (cmd != SG_IO)
|
||||
pr_info("aoe: unknown ioctl 0x%x\n", cmd);
|
||||
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
static const struct block_device_operations aoe_bdops = {
|
||||
.open = aoeblk_open,
|
||||
.release = aoeblk_release,
|
||||
.ioctl = aoeblk_ioctl,
|
||||
.getgeo = aoeblk_getgeo,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
@ -212,6 +268,18 @@ aoeblk_gdalloc(void *vp)
|
|||
struct request_queue *q;
|
||||
enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, };
|
||||
ulong flags;
|
||||
int late = 0;
|
||||
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
if (d->flags & DEVFL_GDALLOC
|
||||
&& !(d->flags & DEVFL_TKILL)
|
||||
&& !(d->flags & DEVFL_GD_NOW))
|
||||
d->flags |= DEVFL_GD_NOW;
|
||||
else
|
||||
late = 1;
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
if (late)
|
||||
return;
|
||||
|
||||
gd = alloc_disk(AOE_PARTITIONS);
|
||||
if (gd == NULL) {
|
||||
|
@ -231,23 +299,24 @@ aoeblk_gdalloc(void *vp)
|
|||
if (q == NULL) {
|
||||
pr_err("aoe: cannot allocate block queue for %ld.%d\n",
|
||||
d->aoemajor, d->aoeminor);
|
||||
mempool_destroy(mp);
|
||||
goto err_disk;
|
||||
goto err_mempool;
|
||||
}
|
||||
|
||||
d->blkq = blk_alloc_queue(GFP_KERNEL);
|
||||
if (!d->blkq)
|
||||
goto err_mempool;
|
||||
d->blkq->backing_dev_info.name = "aoe";
|
||||
if (bdi_init(&d->blkq->backing_dev_info))
|
||||
goto err_blkq;
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
blk_queue_max_hw_sectors(d->blkq, BLK_DEF_MAX_SECTORS);
|
||||
WARN_ON(!(d->flags & DEVFL_GD_NOW));
|
||||
WARN_ON(!(d->flags & DEVFL_GDALLOC));
|
||||
WARN_ON(d->flags & DEVFL_TKILL);
|
||||
WARN_ON(d->gd);
|
||||
WARN_ON(d->flags & DEVFL_UP);
|
||||
blk_queue_max_hw_sectors(q, BLK_DEF_MAX_SECTORS);
|
||||
q->backing_dev_info.name = "aoe";
|
||||
q->backing_dev_info.ra_pages = READ_AHEAD / PAGE_CACHE_SIZE;
|
||||
d->bufpool = mp;
|
||||
d->blkq = gd->queue = q;
|
||||
q->queuedata = d;
|
||||
d->gd = gd;
|
||||
if (aoe_maxsectors)
|
||||
blk_queue_max_hw_sectors(q, aoe_maxsectors);
|
||||
gd->major = AOE_MAJOR;
|
||||
gd->first_minor = d->sysminor;
|
||||
gd->fops = &aoe_bdops;
|
||||
|
@ -263,18 +332,21 @@ aoeblk_gdalloc(void *vp)
|
|||
|
||||
add_disk(gd);
|
||||
aoedisk_add_sysfs(d);
|
||||
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
WARN_ON(!(d->flags & DEVFL_GD_NOW));
|
||||
d->flags &= ~DEVFL_GD_NOW;
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
return;
|
||||
|
||||
err_blkq:
|
||||
blk_cleanup_queue(d->blkq);
|
||||
d->blkq = NULL;
|
||||
err_mempool:
|
||||
mempool_destroy(d->bufpool);
|
||||
mempool_destroy(mp);
|
||||
err_disk:
|
||||
put_disk(gd);
|
||||
err:
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
d->flags &= ~DEVFL_GDALLOC;
|
||||
d->flags &= ~DEVFL_GD_NOW;
|
||||
schedule_work(&d->work);
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,11 @@ struct ErrMsg {
|
|||
};
|
||||
|
||||
static DEFINE_MUTEX(aoechr_mutex);
|
||||
|
||||
/* A ring buffer of error messages, to be read through
|
||||
* "/dev/etherd/err". When no messages are present,
|
||||
* readers will block waiting for messages to appear.
|
||||
*/
|
||||
static struct ErrMsg emsgs[NMSG];
|
||||
static int emsgs_head_idx, emsgs_tail_idx;
|
||||
static struct completion emsgs_comp;
|
||||
|
@ -282,7 +287,7 @@ aoechr_init(void)
|
|||
int n, i;
|
||||
|
||||
n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops);
|
||||
if (n < 0) {
|
||||
if (n < 0) {
|
||||
printk(KERN_ERR "aoe: can't register char device\n");
|
||||
return n;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,7 +15,6 @@
|
|||
#include "aoe.h"
|
||||
|
||||
static void dummy_timer(ulong);
|
||||
static void aoedev_freedev(struct aoedev *);
|
||||
static void freetgt(struct aoedev *d, struct aoetgt *t);
|
||||
static void skbpoolfree(struct aoedev *d);
|
||||
|
||||
|
@ -69,25 +68,34 @@ minor_get_static(ulong *sysminor, ulong aoemaj, int aoemin)
|
|||
NPERSHELF = 16,
|
||||
};
|
||||
|
||||
if (aoemin >= NPERSHELF) {
|
||||
pr_err("aoe: %s %d slots per shelf\n",
|
||||
"static minor device numbers support only",
|
||||
NPERSHELF);
|
||||
error = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
n = aoemaj * NPERSHELF + aoemin;
|
||||
if (aoemin >= NPERSHELF || n >= N_DEVS) {
|
||||
if (n >= N_DEVS) {
|
||||
pr_err("aoe: %s with e%ld.%d\n",
|
||||
"cannot use static minor device numbers",
|
||||
aoemaj, aoemin);
|
||||
error = -1;
|
||||
} else {
|
||||
spin_lock_irqsave(&used_minors_lock, flags);
|
||||
if (test_bit(n, used_minors)) {
|
||||
pr_err("aoe: %s %lu\n",
|
||||
"existing device already has static minor number",
|
||||
n);
|
||||
error = -1;
|
||||
} else
|
||||
set_bit(n, used_minors);
|
||||
spin_unlock_irqrestore(&used_minors_lock, flags);
|
||||
goto out;
|
||||
}
|
||||
|
||||
*sysminor = n;
|
||||
spin_lock_irqsave(&used_minors_lock, flags);
|
||||
if (test_bit(n, used_minors)) {
|
||||
pr_err("aoe: %s %lu\n",
|
||||
"existing device already has static minor number",
|
||||
n);
|
||||
error = -1;
|
||||
} else
|
||||
set_bit(n, used_minors);
|
||||
spin_unlock_irqrestore(&used_minors_lock, flags);
|
||||
*sysminor = n * AOE_PARTITIONS;
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -170,41 +178,50 @@ aoe_failip(struct aoedev *d)
|
|||
aoe_end_request(d, rq, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
downdev_frame(struct list_head *pos)
|
||||
{
|
||||
struct frame *f;
|
||||
|
||||
f = list_entry(pos, struct frame, head);
|
||||
list_del(pos);
|
||||
if (f->buf) {
|
||||
f->buf->nframesout--;
|
||||
aoe_failbuf(f->t->d, f->buf);
|
||||
}
|
||||
aoe_freetframe(f);
|
||||
}
|
||||
|
||||
void
|
||||
aoedev_downdev(struct aoedev *d)
|
||||
{
|
||||
struct aoetgt *t, **tt, **te;
|
||||
struct frame *f;
|
||||
struct list_head *head, *pos, *nx;
|
||||
struct request *rq;
|
||||
int i;
|
||||
|
||||
d->flags &= ~DEVFL_UP;
|
||||
|
||||
/* clean out active buffers */
|
||||
/* clean out active and to-be-retransmitted buffers */
|
||||
for (i = 0; i < NFACTIVE; i++) {
|
||||
head = &d->factive[i];
|
||||
list_for_each_safe(pos, nx, head) {
|
||||
f = list_entry(pos, struct frame, head);
|
||||
list_del(pos);
|
||||
if (f->buf) {
|
||||
f->buf->nframesout--;
|
||||
aoe_failbuf(d, f->buf);
|
||||
}
|
||||
aoe_freetframe(f);
|
||||
}
|
||||
list_for_each_safe(pos, nx, head)
|
||||
downdev_frame(pos);
|
||||
}
|
||||
head = &d->rexmitq;
|
||||
list_for_each_safe(pos, nx, head)
|
||||
downdev_frame(pos);
|
||||
|
||||
/* reset window dressings */
|
||||
tt = d->targets;
|
||||
te = tt + NTARGETS;
|
||||
te = tt + d->ntargets;
|
||||
for (; tt < te && (t = *tt); tt++) {
|
||||
t->maxout = t->nframes;
|
||||
aoecmd_wreset(t);
|
||||
t->nout = 0;
|
||||
}
|
||||
|
||||
/* clean out the in-process request (if any) */
|
||||
aoe_failip(d);
|
||||
d->htgt = NULL;
|
||||
|
||||
/* fast fail all pending I/O */
|
||||
if (d->blkq) {
|
||||
|
@ -218,12 +235,48 @@ aoedev_downdev(struct aoedev *d)
|
|||
set_capacity(d->gd, 0);
|
||||
}
|
||||
|
||||
/* return whether the user asked for this particular
|
||||
* device to be flushed
|
||||
*/
|
||||
static int
|
||||
user_req(char *s, size_t slen, struct aoedev *d)
|
||||
{
|
||||
char *p;
|
||||
size_t lim;
|
||||
|
||||
if (!d->gd)
|
||||
return 0;
|
||||
p = strrchr(d->gd->disk_name, '/');
|
||||
if (!p)
|
||||
p = d->gd->disk_name;
|
||||
else
|
||||
p += 1;
|
||||
lim = sizeof(d->gd->disk_name);
|
||||
lim -= p - d->gd->disk_name;
|
||||
if (slen < lim)
|
||||
lim = slen;
|
||||
|
||||
return !strncmp(s, p, lim);
|
||||
}
|
||||
|
||||
static void
|
||||
aoedev_freedev(struct aoedev *d)
|
||||
freedev(struct aoedev *d)
|
||||
{
|
||||
struct aoetgt **t, **e;
|
||||
int freeing = 0;
|
||||
unsigned long flags;
|
||||
|
||||
cancel_work_sync(&d->work);
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
if (d->flags & DEVFL_TKILL
|
||||
&& !(d->flags & DEVFL_FREEING)) {
|
||||
d->flags |= DEVFL_FREEING;
|
||||
freeing = 1;
|
||||
}
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
if (!freeing)
|
||||
return;
|
||||
|
||||
del_timer_sync(&d->timer);
|
||||
if (d->gd) {
|
||||
aoedisk_rm_sysfs(d);
|
||||
del_gendisk(d->gd);
|
||||
|
@ -231,61 +284,113 @@ aoedev_freedev(struct aoedev *d)
|
|||
blk_cleanup_queue(d->blkq);
|
||||
}
|
||||
t = d->targets;
|
||||
e = t + NTARGETS;
|
||||
e = t + d->ntargets;
|
||||
for (; t < e && *t; t++)
|
||||
freetgt(d, *t);
|
||||
if (d->bufpool)
|
||||
mempool_destroy(d->bufpool);
|
||||
skbpoolfree(d);
|
||||
minor_free(d->sysminor);
|
||||
kfree(d);
|
||||
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
d->flags |= DEVFL_FREED;
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
}
|
||||
|
||||
int
|
||||
aoedev_flush(const char __user *str, size_t cnt)
|
||||
enum flush_parms {
|
||||
NOT_EXITING = 0,
|
||||
EXITING = 1,
|
||||
};
|
||||
|
||||
static int
|
||||
flush(const char __user *str, size_t cnt, int exiting)
|
||||
{
|
||||
ulong flags;
|
||||
struct aoedev *d, **dd;
|
||||
struct aoedev *rmd = NULL;
|
||||
char buf[16];
|
||||
int all = 0;
|
||||
int specified = 0; /* flush a specific device */
|
||||
unsigned int skipflags;
|
||||
|
||||
if (cnt >= 3) {
|
||||
skipflags = DEVFL_GDALLOC | DEVFL_NEWSIZE | DEVFL_TKILL;
|
||||
|
||||
if (!exiting && cnt >= 3) {
|
||||
if (cnt > sizeof buf)
|
||||
cnt = sizeof buf;
|
||||
if (copy_from_user(buf, str, cnt))
|
||||
return -EFAULT;
|
||||
all = !strncmp(buf, "all", 3);
|
||||
if (!all)
|
||||
specified = 1;
|
||||
}
|
||||
|
||||
flush_scheduled_work();
|
||||
/* pass one: without sleeping, do aoedev_downdev */
|
||||
spin_lock_irqsave(&devlist_lock, flags);
|
||||
dd = &devlist;
|
||||
while ((d = *dd)) {
|
||||
for (d = devlist; d; d = d->next) {
|
||||
spin_lock(&d->lock);
|
||||
if ((!all && (d->flags & DEVFL_UP))
|
||||
|| (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
|
||||
if (exiting) {
|
||||
/* unconditionally take each device down */
|
||||
} else if (specified) {
|
||||
if (!user_req(buf, cnt, d))
|
||||
goto cont;
|
||||
} else if ((!all && (d->flags & DEVFL_UP))
|
||||
|| d->flags & skipflags
|
||||
|| d->nopen
|
||||
|| d->ref) {
|
||||
spin_unlock(&d->lock);
|
||||
dd = &d->next;
|
||||
continue;
|
||||
}
|
||||
*dd = d->next;
|
||||
|| d->ref)
|
||||
goto cont;
|
||||
|
||||
aoedev_downdev(d);
|
||||
d->flags |= DEVFL_TKILL;
|
||||
cont:
|
||||
spin_unlock(&d->lock);
|
||||
d->next = rmd;
|
||||
rmd = d;
|
||||
}
|
||||
spin_unlock_irqrestore(&devlist_lock, flags);
|
||||
while ((d = rmd)) {
|
||||
rmd = d->next;
|
||||
del_timer_sync(&d->timer);
|
||||
aoedev_freedev(d); /* must be able to sleep */
|
||||
|
||||
/* pass two: call freedev, which might sleep,
|
||||
* for aoedevs marked with DEVFL_TKILL
|
||||
*/
|
||||
restart:
|
||||
spin_lock_irqsave(&devlist_lock, flags);
|
||||
for (d = devlist; d; d = d->next) {
|
||||
spin_lock(&d->lock);
|
||||
if (d->flags & DEVFL_TKILL
|
||||
&& !(d->flags & DEVFL_FREEING)) {
|
||||
spin_unlock(&d->lock);
|
||||
spin_unlock_irqrestore(&devlist_lock, flags);
|
||||
freedev(d);
|
||||
goto restart;
|
||||
}
|
||||
spin_unlock(&d->lock);
|
||||
}
|
||||
|
||||
/* pass three: remove aoedevs marked with DEVFL_FREED */
|
||||
for (dd = &devlist, d = *dd; d; d = *dd) {
|
||||
struct aoedev *doomed = NULL;
|
||||
|
||||
spin_lock(&d->lock);
|
||||
if (d->flags & DEVFL_FREED) {
|
||||
*dd = d->next;
|
||||
doomed = d;
|
||||
} else {
|
||||
dd = &d->next;
|
||||
}
|
||||
spin_unlock(&d->lock);
|
||||
if (doomed)
|
||||
kfree(doomed->targets);
|
||||
kfree(doomed);
|
||||
}
|
||||
spin_unlock_irqrestore(&devlist_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
aoedev_flush(const char __user *str, size_t cnt)
|
||||
{
|
||||
return flush(str, cnt, NOT_EXITING);
|
||||
}
|
||||
|
||||
/* This has been confirmed to occur once with Tms=3*1000 due to the
|
||||
* driver changing link and not processing its transmit ring. The
|
||||
* problem is hard enough to solve by returning an error that I'm
|
||||
|
@ -332,13 +437,20 @@ aoedev_by_aoeaddr(ulong maj, int min, int do_alloc)
|
|||
struct aoedev *d;
|
||||
int i;
|
||||
ulong flags;
|
||||
ulong sysminor;
|
||||
ulong sysminor = 0;
|
||||
|
||||
spin_lock_irqsave(&devlist_lock, flags);
|
||||
|
||||
for (d=devlist; d; d=d->next)
|
||||
if (d->aoemajor == maj && d->aoeminor == min) {
|
||||
spin_lock(&d->lock);
|
||||
if (d->flags & DEVFL_TKILL) {
|
||||
spin_unlock(&d->lock);
|
||||
d = NULL;
|
||||
goto out;
|
||||
}
|
||||
d->ref++;
|
||||
spin_unlock(&d->lock);
|
||||
break;
|
||||
}
|
||||
if (d || !do_alloc || minor_get(&sysminor, maj, min) < 0)
|
||||
|
@ -346,6 +458,13 @@ aoedev_by_aoeaddr(ulong maj, int min, int do_alloc)
|
|||
d = kcalloc(1, sizeof *d, GFP_ATOMIC);
|
||||
if (!d)
|
||||
goto out;
|
||||
d->targets = kcalloc(NTARGETS, sizeof(*d->targets), GFP_ATOMIC);
|
||||
if (!d->targets) {
|
||||
kfree(d);
|
||||
d = NULL;
|
||||
goto out;
|
||||
}
|
||||
d->ntargets = NTARGETS;
|
||||
INIT_WORK(&d->work, aoecmd_sleepwork);
|
||||
spin_lock_init(&d->lock);
|
||||
skb_queue_head_init(&d->skbpool);
|
||||
|
@ -359,10 +478,12 @@ aoedev_by_aoeaddr(ulong maj, int min, int do_alloc)
|
|||
d->ref = 1;
|
||||
for (i = 0; i < NFACTIVE; i++)
|
||||
INIT_LIST_HEAD(&d->factive[i]);
|
||||
INIT_LIST_HEAD(&d->rexmitq);
|
||||
d->sysminor = sysminor;
|
||||
d->aoemajor = maj;
|
||||
d->aoeminor = min;
|
||||
d->mintimer = MINTIMER;
|
||||
d->rttavg = RTTAVG_INIT;
|
||||
d->rttdev = RTTDEV_INIT;
|
||||
d->next = devlist;
|
||||
devlist = d;
|
||||
out:
|
||||
|
@ -396,21 +517,9 @@ freetgt(struct aoedev *d, struct aoetgt *t)
|
|||
void
|
||||
aoedev_exit(void)
|
||||
{
|
||||
struct aoedev *d;
|
||||
ulong flags;
|
||||
|
||||
flush_scheduled_work();
|
||||
aoe_flush_iocq();
|
||||
while ((d = devlist)) {
|
||||
devlist = d->next;
|
||||
|
||||
spin_lock_irqsave(&d->lock, flags);
|
||||
aoedev_downdev(d);
|
||||
d->flags |= DEVFL_TKILL;
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
|
||||
del_timer_sync(&d->timer);
|
||||
aoedev_freedev(d);
|
||||
}
|
||||
flush(NULL, 0, EXITING);
|
||||
}
|
||||
|
||||
int __init
|
||||
|
|
|
@ -105,7 +105,7 @@ aoe_init(void)
|
|||
aoechr_exit();
|
||||
chr_fail:
|
||||
aoedev_exit();
|
||||
|
||||
|
||||
printk(KERN_INFO "aoe: initialisation failure.\n");
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ enum {
|
|||
|
||||
static char aoe_iflist[IFLISTSZ];
|
||||
module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600);
|
||||
MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\"");
|
||||
MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=dev1[,dev2...]");
|
||||
|
||||
static wait_queue_head_t txwq;
|
||||
static struct ktstate kts;
|
||||
|
@ -52,13 +52,18 @@ static struct sk_buff_head skbtxq;
|
|||
|
||||
/* enters with txlock held */
|
||||
static int
|
||||
tx(void)
|
||||
tx(void) __must_hold(&txlock)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct net_device *ifp;
|
||||
|
||||
while ((skb = skb_dequeue(&skbtxq))) {
|
||||
spin_unlock_irq(&txlock);
|
||||
dev_queue_xmit(skb);
|
||||
ifp = skb->dev;
|
||||
if (dev_queue_xmit(skb) == NET_XMIT_DROP && net_ratelimit())
|
||||
pr_warn("aoe: packet could not be sent on %s. %s\n",
|
||||
ifp ? ifp->name : "netif",
|
||||
"consider increasing tx_queue_len");
|
||||
spin_lock_irq(&txlock);
|
||||
}
|
||||
return 0;
|
||||
|
@ -119,8 +124,8 @@ aoenet_xmit(struct sk_buff_head *queue)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (1) len doesn't include the header by default. I want this.
|
||||
/*
|
||||
* (1) len doesn't include the header by default. I want this.
|
||||
*/
|
||||
static int
|
||||
aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev)
|
||||
|
|
|
@ -228,6 +228,20 @@ static void dmatest_callback(void *arg)
|
|||
wake_up_all(done->wait);
|
||||
}
|
||||
|
||||
static inline void unmap_src(struct device *dev, dma_addr_t *addr, size_t len,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--)
|
||||
dma_unmap_single(dev, addr[count], len, DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
static inline void unmap_dst(struct device *dev, dma_addr_t *addr, size_t len,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--)
|
||||
dma_unmap_single(dev, addr[count], len, DMA_BIDIRECTIONAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function repeatedly tests DMA transfers of various lengths and
|
||||
* offsets for a given operation type until it is told to exit by
|
||||
|
@ -353,15 +367,35 @@ static int dmatest_func(void *data)
|
|||
|
||||
dma_srcs[i] = dma_map_single(dev->dev, buf, len,
|
||||
DMA_TO_DEVICE);
|
||||
ret = dma_mapping_error(dev->dev, dma_srcs[i]);
|
||||
if (ret) {
|
||||
unmap_src(dev->dev, dma_srcs, len, i);
|
||||
pr_warn("%s: #%u: mapping error %d with "
|
||||
"src_off=0x%x len=0x%x\n",
|
||||
thread_name, total_tests - 1, ret,
|
||||
src_off, len);
|
||||
failed_tests++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
|
||||
for (i = 0; i < dst_cnt; i++) {
|
||||
dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
|
||||
test_buf_size,
|
||||
DMA_BIDIRECTIONAL);
|
||||
ret = dma_mapping_error(dev->dev, dma_dsts[i]);
|
||||
if (ret) {
|
||||
unmap_src(dev->dev, dma_srcs, len, src_cnt);
|
||||
unmap_dst(dev->dev, dma_dsts, test_buf_size, i);
|
||||
pr_warn("%s: #%u: mapping error %d with "
|
||||
"dst_off=0x%x len=0x%x\n",
|
||||
thread_name, total_tests - 1, ret,
|
||||
dst_off, test_buf_size);
|
||||
failed_tests++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (thread->type == DMA_MEMCPY)
|
||||
tx = dev->device_prep_dma_memcpy(chan,
|
||||
dma_dsts[0] + dst_off,
|
||||
|
@ -383,13 +417,8 @@ static int dmatest_func(void *data)
|
|||
}
|
||||
|
||||
if (!tx) {
|
||||
for (i = 0; i < src_cnt; i++)
|
||||
dma_unmap_single(dev->dev, dma_srcs[i], len,
|
||||
DMA_TO_DEVICE);
|
||||
for (i = 0; i < dst_cnt; i++)
|
||||
dma_unmap_single(dev->dev, dma_dsts[i],
|
||||
test_buf_size,
|
||||
DMA_BIDIRECTIONAL);
|
||||
unmap_src(dev->dev, dma_srcs, len, src_cnt);
|
||||
unmap_dst(dev->dev, dma_dsts, test_buf_size, dst_cnt);
|
||||
pr_warning("%s: #%u: prep error with src_off=0x%x "
|
||||
"dst_off=0x%x len=0x%x\n",
|
||||
thread_name, total_tests - 1,
|
||||
|
@ -443,9 +472,7 @@ static int dmatest_func(void *data)
|
|||
}
|
||||
|
||||
/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
|
||||
for (i = 0; i < dst_cnt; i++)
|
||||
dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,
|
||||
DMA_BIDIRECTIONAL);
|
||||
unmap_dst(dev->dev, dma_dsts, test_buf_size, dst_cnt);
|
||||
|
||||
error_count = 0;
|
||||
|
||||
|
|
|
@ -1397,10 +1397,7 @@ int do_read_error(struct nandsim *ns, int num)
|
|||
unsigned int page_no = ns->regs.row;
|
||||
|
||||
if (read_error(page_no)) {
|
||||
int i;
|
||||
memset(ns->buf.byte, 0xFF, num);
|
||||
for (i = 0; i < num; ++i)
|
||||
ns->buf.byte[i] = random32();
|
||||
prandom_bytes(ns->buf.byte, num);
|
||||
NS_WARN("simulating read error in page %u\n", page_no);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1832,7 +1832,6 @@ int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
|
|||
bool config_hash)
|
||||
{
|
||||
struct bnx2x_config_rss_params params = {NULL};
|
||||
int i;
|
||||
|
||||
/* Although RSS is meaningless when there is a single HW queue we
|
||||
* still need it enabled in order to have HW Rx hash generated.
|
||||
|
@ -1864,9 +1863,7 @@ int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
|
|||
|
||||
if (config_hash) {
|
||||
/* RSS keys */
|
||||
for (i = 0; i < sizeof(params.rss_key) / 4; i++)
|
||||
params.rss_key[i] = random32();
|
||||
|
||||
prandom_bytes(params.rss_key, sizeof(params.rss_key));
|
||||
__set_bit(BNX2X_RSS_SET_SRCH, ¶ms.rss_flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -156,11 +156,7 @@ config PRISM54
|
|||
---help---
|
||||
This enables support for FullMAC PCI/Cardbus prism54 devices. This
|
||||
driver is now deprecated in favor for the SoftMAC driver, p54pci.
|
||||
p54pci supports FullMAC PCI/Cardbus devices as well. For details on
|
||||
the scheduled removal of this driver on the kernel see the feature
|
||||
removal schedule:
|
||||
|
||||
Documentation/feature-removal-schedule.txt
|
||||
p54pci supports FullMAC PCI/Cardbus devices as well.
|
||||
|
||||
For more information refer to the p54 wiki:
|
||||
|
||||
|
|
|
@ -488,14 +488,8 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
|
|||
depth++;
|
||||
pathp = (char *)p;
|
||||
p = ALIGN(p + strlen(pathp) + 1, 4);
|
||||
if ((*pathp) == '/') {
|
||||
const char *lp, *np;
|
||||
for (lp = NULL, np = pathp; *np; np++)
|
||||
if ((*np) == '/')
|
||||
lp = np+1;
|
||||
if (lp != NULL)
|
||||
pathp = lp;
|
||||
}
|
||||
if (*pathp == '/')
|
||||
pathp = kbasename(pathp);
|
||||
rc = it(p, pathp, depth, data);
|
||||
if (rc != 0)
|
||||
break;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#define ASUS_NB_WMI_FILE "asus-nb-wmi"
|
||||
|
||||
MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>");
|
||||
MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>");
|
||||
MODULE_DESCRIPTION("Asus Notebooks WMI Hotkey Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
#include "asus-wmi.h"
|
||||
|
||||
MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>, "
|
||||
MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>, "
|
||||
"Yong Wang <yong.y.wang@intel.com>");
|
||||
MODULE_DESCRIPTION("Asus Generic WMI Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#define EEEPC_WMI_FILE "eeepc-wmi"
|
||||
|
||||
MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>");
|
||||
MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>");
|
||||
MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
@ -269,6 +269,15 @@ config RTC_DRV_X1205
|
|||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-x1205.
|
||||
|
||||
config RTC_DRV_PCF8523
|
||||
tristate "NXP PCF8523"
|
||||
help
|
||||
If you say yes here you get support for the NXP PCF8523 RTC
|
||||
chips.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-pcf8523.
|
||||
|
||||
config RTC_DRV_PCF8563
|
||||
tristate "Philips PCF8563/Epson RTC8564"
|
||||
help
|
||||
|
@ -600,6 +609,16 @@ config RTC_DRV_DA9052
|
|||
Say y here to support the RTC driver for Dialog Semiconductor
|
||||
DA9052-BC and DA9053-AA/Bx PMICs.
|
||||
|
||||
config RTC_DRV_DA9055
|
||||
tristate "Dialog Semiconductor DA9055 RTC"
|
||||
depends on MFD_DA9055
|
||||
help
|
||||
If you say yes here you will get support for the
|
||||
RTC of the Dialog DA9055 PMIC.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-da9055
|
||||
|
||||
config RTC_DRV_EFI
|
||||
tristate "EFI RTC"
|
||||
depends on IA64
|
||||
|
@ -768,7 +787,7 @@ config RTC_DRV_DAVINCI
|
|||
|
||||
config RTC_DRV_IMXDI
|
||||
tristate "Freescale IMX DryIce Real Time Clock"
|
||||
depends on SOC_IMX25
|
||||
depends on ARCH_MXC
|
||||
help
|
||||
Support for Freescale IMX DryIce RTC
|
||||
|
||||
|
@ -777,11 +796,13 @@ config RTC_DRV_IMXDI
|
|||
|
||||
config RTC_DRV_OMAP
|
||||
tristate "TI OMAP1"
|
||||
depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX
|
||||
depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX || SOC_AM33XX
|
||||
help
|
||||
Say "yes" here to support the real time clock on TI OMAP1 and
|
||||
DA8xx/OMAP-L13x chips. This driver can also be built as a
|
||||
module called rtc-omap.
|
||||
Say "yes" here to support the on chip real time clock
|
||||
present on TI OMAP1, AM33xx and DA8xx/OMAP-L13x.
|
||||
|
||||
This driver can also be built as a module, if so, module
|
||||
will be called rtc-omap.
|
||||
|
||||
config HAVE_S3C_RTC
|
||||
bool
|
||||
|
|
|
@ -29,6 +29,7 @@ obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
|
|||
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
|
||||
obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o
|
||||
obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
|
||||
obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o
|
||||
obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o
|
||||
obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
|
||||
obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o
|
||||
|
@ -76,6 +77,7 @@ obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
|
|||
obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o
|
||||
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
|
||||
obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o
|
||||
obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o
|
||||
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
|
||||
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
|
||||
obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o
|
||||
|
|
|
@ -0,0 +1,413 @@
|
|||
/*
|
||||
* Real time clock driver for DA9055
|
||||
*
|
||||
* 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/da9055/core.h>
|
||||
#include <linux/mfd/da9055/reg.h>
|
||||
#include <linux/mfd/da9055/pdata.h>
|
||||
|
||||
struct da9055_rtc {
|
||||
struct rtc_device *rtc;
|
||||
struct da9055 *da9055;
|
||||
int alarm_enable;
|
||||
};
|
||||
|
||||
static int da9055_rtc_enable_alarm(struct da9055_rtc *rtc, bool enable)
|
||||
{
|
||||
int ret;
|
||||
if (enable) {
|
||||
ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y,
|
||||
DA9055_RTC_ALM_EN,
|
||||
DA9055_RTC_ALM_EN);
|
||||
if (ret != 0)
|
||||
dev_err(rtc->da9055->dev, "Failed to enable ALM: %d\n",
|
||||
ret);
|
||||
rtc->alarm_enable = 1;
|
||||
} else {
|
||||
ret = da9055_reg_update(rtc->da9055, DA9055_REG_ALARM_Y,
|
||||
DA9055_RTC_ALM_EN, 0);
|
||||
if (ret != 0)
|
||||
dev_err(rtc->da9055->dev,
|
||||
"Failed to disable ALM: %d\n", ret);
|
||||
rtc->alarm_enable = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t da9055_rtc_alm_irq(int irq, void *data)
|
||||
{
|
||||
struct da9055_rtc *rtc = data;
|
||||
|
||||
da9055_rtc_enable_alarm(rtc, 0);
|
||||
rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int da9055_read_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm)
|
||||
{
|
||||
int ret;
|
||||
uint8_t v[5];
|
||||
|
||||
ret = da9055_group_read(da9055, DA9055_REG_ALARM_MI, 5, v);
|
||||
if (ret != 0) {
|
||||
dev_err(da9055->dev, "Failed to group read ALM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtc_tm->tm_year = (v[4] & DA9055_RTC_ALM_YEAR) + 100;
|
||||
rtc_tm->tm_mon = (v[3] & DA9055_RTC_ALM_MONTH) - 1;
|
||||
rtc_tm->tm_mday = v[2] & DA9055_RTC_ALM_DAY;
|
||||
rtc_tm->tm_hour = v[1] & DA9055_RTC_ALM_HOUR;
|
||||
rtc_tm->tm_min = v[0] & DA9055_RTC_ALM_MIN;
|
||||
|
||||
return rtc_valid_tm(rtc_tm);
|
||||
}
|
||||
|
||||
static int da9055_set_alarm(struct da9055 *da9055, struct rtc_time *rtc_tm)
|
||||
{
|
||||
int ret;
|
||||
uint8_t v[2];
|
||||
|
||||
rtc_tm->tm_year -= 100;
|
||||
rtc_tm->tm_mon += 1;
|
||||
|
||||
ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MI,
|
||||
DA9055_RTC_ALM_MIN, rtc_tm->tm_min);
|
||||
if (ret != 0) {
|
||||
dev_err(da9055->dev, "Failed to write ALRM MIN: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
v[0] = rtc_tm->tm_hour;
|
||||
v[1] = rtc_tm->tm_mday;
|
||||
|
||||
ret = da9055_group_write(da9055, DA9055_REG_ALARM_H, 2, v);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO,
|
||||
DA9055_RTC_ALM_MONTH, rtc_tm->tm_mon);
|
||||
if (ret < 0)
|
||||
dev_err(da9055->dev, "Failed to write ALM Month:%d\n", ret);
|
||||
|
||||
ret = da9055_reg_update(da9055, DA9055_REG_ALARM_Y,
|
||||
DA9055_RTC_ALM_YEAR, rtc_tm->tm_year);
|
||||
if (ret < 0)
|
||||
dev_err(da9055->dev, "Failed to write ALM Year:%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9055_rtc_get_alarm_status(struct da9055 *da9055)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = da9055_reg_read(da9055, DA9055_REG_ALARM_Y);
|
||||
if (ret < 0) {
|
||||
dev_err(da9055->dev, "Failed to read ALM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret &= DA9055_RTC_ALM_EN;
|
||||
return (ret > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int da9055_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
|
||||
{
|
||||
struct da9055_rtc *rtc = dev_get_drvdata(dev);
|
||||
uint8_t v[6];
|
||||
int ret;
|
||||
|
||||
ret = da9055_reg_read(rtc->da9055, DA9055_REG_COUNT_S);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Registers are only valid when RTC_READ
|
||||
* status bit is asserted
|
||||
*/
|
||||
if (!(ret & DA9055_RTC_READ))
|
||||
return -EBUSY;
|
||||
|
||||
ret = da9055_group_read(rtc->da9055, DA9055_REG_COUNT_S, 6, v);
|
||||
if (ret < 0) {
|
||||
dev_err(rtc->da9055->dev, "Failed to read RTC time : %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtc_tm->tm_year = (v[5] & DA9055_RTC_YEAR) + 100;
|
||||
rtc_tm->tm_mon = (v[4] & DA9055_RTC_MONTH) - 1;
|
||||
rtc_tm->tm_mday = v[3] & DA9055_RTC_DAY;
|
||||
rtc_tm->tm_hour = v[2] & DA9055_RTC_HOUR;
|
||||
rtc_tm->tm_min = v[1] & DA9055_RTC_MIN;
|
||||
rtc_tm->tm_sec = v[0] & DA9055_RTC_SEC;
|
||||
|
||||
return rtc_valid_tm(rtc_tm);
|
||||
}
|
||||
|
||||
static int da9055_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct da9055_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 da9055_group_write(rtc->da9055, DA9055_REG_COUNT_S, 6, v);
|
||||
}
|
||||
|
||||
static int da9055_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
int ret;
|
||||
struct rtc_time *tm = &alrm->time;
|
||||
struct da9055_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
ret = da9055_read_alarm(rtc->da9055, tm);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
alrm->enabled = da9055_rtc_get_alarm_status(rtc->da9055);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da9055_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
int ret;
|
||||
struct rtc_time *tm = &alrm->time;
|
||||
struct da9055_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
ret = da9055_rtc_enable_alarm(rtc, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = da9055_set_alarm(rtc->da9055, tm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = da9055_rtc_enable_alarm(rtc, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9055_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct da9055_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
return da9055_rtc_enable_alarm(rtc, enabled);
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops da9055_rtc_ops = {
|
||||
.read_time = da9055_rtc_read_time,
|
||||
.set_time = da9055_rtc_set_time,
|
||||
.read_alarm = da9055_rtc_read_alarm,
|
||||
.set_alarm = da9055_rtc_set_alarm,
|
||||
.alarm_irq_enable = da9055_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int __init da9055_rtc_device_init(struct da9055 *da9055,
|
||||
struct da9055_pdata *pdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Enable RTC and the internal Crystal */
|
||||
ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B,
|
||||
DA9055_RTC_EN, DA9055_RTC_EN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = da9055_reg_update(da9055, DA9055_REG_EN_32K,
|
||||
DA9055_CRYSTAL_EN, DA9055_CRYSTAL_EN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Enable RTC in Power Down mode */
|
||||
ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B,
|
||||
DA9055_RTC_MODE_PD, DA9055_RTC_MODE_PD);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Enable RTC in Reset mode */
|
||||
if (pdata && pdata->reset_enable) {
|
||||
ret = da9055_reg_update(da9055, DA9055_REG_CONTROL_B,
|
||||
DA9055_RTC_MODE_SD,
|
||||
DA9055_RTC_MODE_SD <<
|
||||
DA9055_RTC_MODE_SD_SHIFT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable the RTC TICK ALM */
|
||||
ret = da9055_reg_update(da9055, DA9055_REG_ALARM_MO,
|
||||
DA9055_RTC_TICK_WAKE_MASK, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da9055_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct da9055_rtc *rtc;
|
||||
struct da9055_pdata *pdata = NULL;
|
||||
int ret, alm_irq;
|
||||
|
||||
rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9055_rtc), GFP_KERNEL);
|
||||
if (!rtc)
|
||||
return -ENOMEM;
|
||||
|
||||
rtc->da9055 = dev_get_drvdata(pdev->dev.parent);
|
||||
pdata = rtc->da9055->dev->platform_data;
|
||||
platform_set_drvdata(pdev, rtc);
|
||||
|
||||
ret = da9055_rtc_device_init(rtc->da9055, pdata);
|
||||
if (ret < 0)
|
||||
goto err_rtc;
|
||||
|
||||
ret = da9055_reg_read(rtc->da9055, DA9055_REG_ALARM_Y);
|
||||
if (ret < 0)
|
||||
goto err_rtc;
|
||||
|
||||
if (ret & DA9055_RTC_ALM_EN)
|
||||
rtc->alarm_enable = 1;
|
||||
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
|
||||
&da9055_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(rtc->rtc)) {
|
||||
ret = PTR_ERR(rtc->rtc);
|
||||
goto err_rtc;
|
||||
}
|
||||
|
||||
alm_irq = platform_get_irq_byname(pdev, "ALM");
|
||||
alm_irq = regmap_irq_get_virq(rtc->da9055->irq_data, alm_irq);
|
||||
ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL,
|
||||
da9055_rtc_alm_irq,
|
||||
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
|
||||
"ALM", rtc);
|
||||
if (ret != 0)
|
||||
dev_err(rtc->da9055->dev, "irq registration failed: %d\n", ret);
|
||||
|
||||
err_rtc:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int da9055_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct da9055_rtc *rtc = pdev->dev.platform_data;
|
||||
|
||||
rtc_device_unregister(rtc->rtc);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/* Turn off the alarm if it should not be a wake source. */
|
||||
static int da9055_rtc_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev);
|
||||
int ret;
|
||||
|
||||
if (!device_may_wakeup(&pdev->dev)) {
|
||||
/* Disable the ALM IRQ */
|
||||
ret = da9055_rtc_enable_alarm(rtc, 0);
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "Failed to disable RTC ALM\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Enable the alarm if it should be enabled (in case it was disabled to
|
||||
* prevent use as a wake source).
|
||||
*/
|
||||
static int da9055_rtc_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev);
|
||||
int ret;
|
||||
|
||||
if (!device_may_wakeup(&pdev->dev)) {
|
||||
if (rtc->alarm_enable) {
|
||||
ret = da9055_rtc_enable_alarm(rtc, 1);
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to restart RTC ALM\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unconditionally disable the alarm */
|
||||
static int da9055_rtc_freeze(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct da9055_rtc *rtc = dev_get_drvdata(&pdev->dev);
|
||||
int ret;
|
||||
|
||||
ret = da9055_rtc_enable_alarm(rtc, 0);
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "Failed to freeze RTC ALMs\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#else
|
||||
#define da9055_rtc_suspend NULL
|
||||
#define da9055_rtc_resume NULL
|
||||
#define da9055_rtc_freeze NULL
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops da9055_rtc_pm_ops = {
|
||||
.suspend = da9055_rtc_suspend,
|
||||
.resume = da9055_rtc_resume,
|
||||
|
||||
.freeze = da9055_rtc_freeze,
|
||||
.thaw = da9055_rtc_resume,
|
||||
.restore = da9055_rtc_resume,
|
||||
|
||||
.poweroff = da9055_rtc_suspend,
|
||||
};
|
||||
|
||||
static struct platform_driver da9055_rtc_driver = {
|
||||
.probe = da9055_rtc_probe,
|
||||
.remove = da9055_rtc_remove,
|
||||
.driver = {
|
||||
.name = "da9055-rtc",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &da9055_rtc_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(da9055_rtc_driver);
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
MODULE_DESCRIPTION("RTC driver for Dialog DA9055 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:da9055-rtc");
|
|
@ -485,7 +485,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
|
|||
struct resource *res, *mem;
|
||||
int ret = 0;
|
||||
|
||||
davinci_rtc = kzalloc(sizeof(struct davinci_rtc), GFP_KERNEL);
|
||||
davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL);
|
||||
if (!davinci_rtc) {
|
||||
dev_dbg(dev, "could not allocate memory for private data\n");
|
||||
return -ENOMEM;
|
||||
|
@ -494,15 +494,13 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
|
|||
davinci_rtc->irq = platform_get_irq(pdev, 0);
|
||||
if (davinci_rtc->irq < 0) {
|
||||
dev_err(dev, "no RTC irq\n");
|
||||
ret = davinci_rtc->irq;
|
||||
goto fail1;
|
||||
return davinci_rtc->irq;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "no mem resource\n");
|
||||
ret = -EINVAL;
|
||||
goto fail1;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
davinci_rtc->pbase = res->start;
|
||||
|
@ -513,8 +511,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
|
|||
if (!mem) {
|
||||
dev_err(dev, "RTC registers at %08x are not free\n",
|
||||
davinci_rtc->pbase);
|
||||
ret = -EBUSY;
|
||||
goto fail1;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size);
|
||||
|
@ -529,8 +526,9 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
|
|||
davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
|
||||
&davinci_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(davinci_rtc->rtc)) {
|
||||
dev_err(dev, "unable to register RTC device, err %ld\n",
|
||||
PTR_ERR(davinci_rtc->rtc));
|
||||
ret = PTR_ERR(davinci_rtc->rtc);
|
||||
dev_err(dev, "unable to register RTC device, err %d\n",
|
||||
ret);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
|
@ -566,9 +564,6 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
|
|||
iounmap(davinci_rtc->base);
|
||||
fail2:
|
||||
release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size);
|
||||
fail1:
|
||||
kfree(davinci_rtc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -589,8 +584,6 @@ static int __devexit davinci_rtc_remove(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
kfree(davinci_rtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -379,25 +379,6 @@ static long rtc_dev_ioctl(struct file *file,
|
|||
err = put_user(rtc->irq_freq, (unsigned long __user *)uarg);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case RTC_EPOCH_SET:
|
||||
#ifndef rtc_epoch
|
||||
/*
|
||||
* There were no RTC clocks before 1900.
|
||||
*/
|
||||
if (arg < 1900) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
rtc_epoch = arg;
|
||||
err = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case RTC_EPOCH_READ:
|
||||
err = put_user(rtc_epoch, (unsigned long __user *)uarg);
|
||||
break;
|
||||
#endif
|
||||
case RTC_WKALM_SET:
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
if (copy_from_user(&alarm, uarg, sizeof(alarm)))
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <linux/rtc.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
/* DryIce Register Definitions */
|
||||
|
||||
|
@ -495,10 +496,20 @@ static int __devexit dryice_rtc_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id dryice_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx25-rtc" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, dryice_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct platform_driver dryice_rtc_driver = {
|
||||
.driver = {
|
||||
.name = "imxdi_rtc",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(dryice_dt_ids),
|
||||
},
|
||||
.remove = __devexit_p(dryice_rtc_remove),
|
||||
};
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include <linux/rtc.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
|
@ -38,6 +41,8 @@
|
|||
* the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment.
|
||||
*/
|
||||
|
||||
#define DRIVER_NAME "omap_rtc"
|
||||
|
||||
#define OMAP_RTC_BASE 0xfffb4800
|
||||
|
||||
/* RTC registers */
|
||||
|
@ -64,6 +69,9 @@
|
|||
#define OMAP_RTC_COMP_MSB_REG 0x50
|
||||
#define OMAP_RTC_OSC_REG 0x54
|
||||
|
||||
#define OMAP_RTC_KICK0_REG 0x6c
|
||||
#define OMAP_RTC_KICK1_REG 0x70
|
||||
|
||||
/* OMAP_RTC_CTRL_REG bit fields: */
|
||||
#define OMAP_RTC_CTRL_SPLIT (1<<7)
|
||||
#define OMAP_RTC_CTRL_DISABLE (1<<6)
|
||||
|
@ -88,10 +96,18 @@
|
|||
#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
|
||||
#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
|
||||
|
||||
/* OMAP_RTC_KICKER values */
|
||||
#define KICK0_VALUE 0x83e70b13
|
||||
#define KICK1_VALUE 0x95a4f1e0
|
||||
|
||||
#define OMAP_RTC_HAS_KICKER 0x1
|
||||
|
||||
static void __iomem *rtc_base;
|
||||
|
||||
#define rtc_read(addr) __raw_readb(rtc_base + (addr))
|
||||
#define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr))
|
||||
#define rtc_read(addr) readb(rtc_base + (addr))
|
||||
#define rtc_write(val, addr) writeb(val, rtc_base + (addr))
|
||||
|
||||
#define rtc_writel(val, addr) writel(val, rtc_base + (addr))
|
||||
|
||||
|
||||
/* we rely on the rtc framework to handle locking (rtc->ops_lock),
|
||||
|
@ -285,11 +301,38 @@ static struct rtc_class_ops omap_rtc_ops = {
|
|||
static int omap_rtc_alarm;
|
||||
static int omap_rtc_timer;
|
||||
|
||||
#define OMAP_RTC_DATA_DA830_IDX 1
|
||||
|
||||
static struct platform_device_id omap_rtc_devtype[] = {
|
||||
{
|
||||
.name = DRIVER_NAME,
|
||||
}, {
|
||||
.name = "da830-rtc",
|
||||
.driver_data = OMAP_RTC_HAS_KICKER,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, omap_rtc_devtype);
|
||||
|
||||
static const struct of_device_id omap_rtc_of_match[] = {
|
||||
{ .compatible = "ti,da830-rtc",
|
||||
.data = &omap_rtc_devtype[OMAP_RTC_DATA_DA830_IDX],
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
|
||||
|
||||
static int __init omap_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res, *mem;
|
||||
struct rtc_device *rtc;
|
||||
u8 reg, new_ctrl;
|
||||
const struct platform_device_id *id_entry;
|
||||
const struct of_device_id *of_id;
|
||||
|
||||
of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
|
||||
if (of_id)
|
||||
pdev->id_entry = of_id->data;
|
||||
|
||||
omap_rtc_timer = platform_get_irq(pdev, 0);
|
||||
if (omap_rtc_timer <= 0) {
|
||||
|
@ -322,6 +365,16 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
/* Enable the clock/module so that we can access the registers */
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
id_entry = platform_get_device_id(pdev);
|
||||
if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) {
|
||||
rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG);
|
||||
rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG);
|
||||
}
|
||||
|
||||
rtc = rtc_device_register(pdev->name, &pdev->dev,
|
||||
&omap_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(rtc)) {
|
||||
|
@ -398,6 +451,10 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
|
|||
fail1:
|
||||
rtc_device_unregister(rtc);
|
||||
fail0:
|
||||
if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
|
||||
rtc_writel(0, OMAP_RTC_KICK0_REG);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
iounmap(rtc_base);
|
||||
fail:
|
||||
release_mem_region(mem->start, resource_size(mem));
|
||||
|
@ -408,6 +465,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct rtc_device *rtc = platform_get_drvdata(pdev);
|
||||
struct resource *mem = dev_get_drvdata(&rtc->dev);
|
||||
const struct platform_device_id *id_entry =
|
||||
platform_get_device_id(pdev);
|
||||
|
||||
device_init_wakeup(&pdev->dev, 0);
|
||||
|
||||
|
@ -420,6 +479,13 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
|
|||
free_irq(omap_rtc_alarm, rtc);
|
||||
|
||||
rtc_device_unregister(rtc);
|
||||
if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
|
||||
rtc_writel(0, OMAP_RTC_KICK0_REG);
|
||||
|
||||
/* Disable the clock/module */
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
iounmap(rtc_base);
|
||||
release_mem_region(mem->start, resource_size(mem));
|
||||
return 0;
|
||||
|
@ -442,11 +508,17 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
|
|||
else
|
||||
rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
|
||||
|
||||
/* Disable the clock/module */
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_rtc_resume(struct platform_device *pdev)
|
||||
{
|
||||
/* Enable the clock/module so that we can access the registers */
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
disable_irq_wake(omap_rtc_alarm);
|
||||
else
|
||||
|
@ -471,9 +543,11 @@ static struct platform_driver omap_rtc_driver = {
|
|||
.resume = omap_rtc_resume,
|
||||
.shutdown = omap_rtc_shutdown,
|
||||
.driver = {
|
||||
.name = "omap_rtc",
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(omap_rtc_of_match),
|
||||
},
|
||||
.id_table = omap_rtc_devtype,
|
||||
};
|
||||
|
||||
static int __init rtc_init(void)
|
||||
|
|
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Avionic Design GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#define DRIVER_NAME "rtc-pcf8523"
|
||||
|
||||
#define REG_CONTROL1 0x00
|
||||
#define REG_CONTROL1_CAP_SEL (1 << 7)
|
||||
#define REG_CONTROL1_STOP (1 << 5)
|
||||
|
||||
#define REG_CONTROL3 0x02
|
||||
#define REG_CONTROL3_PM_BLD (1 << 7) /* battery low detection disabled */
|
||||
#define REG_CONTROL3_PM_VDD (1 << 6) /* switch-over disabled */
|
||||
#define REG_CONTROL3_PM_DSM (1 << 5) /* direct switching mode */
|
||||
#define REG_CONTROL3_PM_MASK 0xe0
|
||||
|
||||
#define REG_SECONDS 0x03
|
||||
#define REG_SECONDS_OS (1 << 7)
|
||||
|
||||
#define REG_MINUTES 0x04
|
||||
#define REG_HOURS 0x05
|
||||
#define REG_DAYS 0x06
|
||||
#define REG_WEEKDAYS 0x07
|
||||
#define REG_MONTHS 0x08
|
||||
#define REG_YEARS 0x09
|
||||
|
||||
struct pcf8523 {
|
||||
struct rtc_device *rtc;
|
||||
};
|
||||
|
||||
static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
u8 value = 0;
|
||||
int err;
|
||||
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].len = sizeof(reg);
|
||||
msgs[0].buf = ®
|
||||
|
||||
msgs[1].addr = client->addr;
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[1].len = sizeof(value);
|
||||
msgs[1].buf = &value;
|
||||
|
||||
err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
*valuep = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
|
||||
{
|
||||
u8 buffer[2] = { reg, value };
|
||||
struct i2c_msg msg;
|
||||
int err;
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = 0;
|
||||
msg.len = sizeof(buffer);
|
||||
msg.buf = buffer;
|
||||
|
||||
err = i2c_transfer(client->adapter, &msg, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
|
||||
{
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
err = pcf8523_read(client, REG_CONTROL1, &value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (!high)
|
||||
value &= ~REG_CONTROL1_CAP_SEL;
|
||||
else
|
||||
value |= REG_CONTROL1_CAP_SEL;
|
||||
|
||||
err = pcf8523_write(client, REG_CONTROL1, value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
|
||||
{
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
err = pcf8523_read(client, REG_CONTROL3, &value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
value = (value & ~REG_CONTROL3_PM_MASK) | pm;
|
||||
|
||||
err = pcf8523_write(client, REG_CONTROL3, value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf8523_stop_rtc(struct i2c_client *client)
|
||||
{
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
err = pcf8523_read(client, REG_CONTROL1, &value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
value |= REG_CONTROL1_STOP;
|
||||
|
||||
err = pcf8523_write(client, REG_CONTROL1, value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf8523_start_rtc(struct i2c_client *client)
|
||||
{
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
err = pcf8523_read(client, REG_CONTROL1, &value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
value &= ~REG_CONTROL1_STOP;
|
||||
|
||||
err = pcf8523_write(client, REG_CONTROL1, value);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
u8 start = REG_SECONDS, regs[7];
|
||||
struct i2c_msg msgs[2];
|
||||
int err;
|
||||
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].len = 1;
|
||||
msgs[0].buf = &start;
|
||||
|
||||
msgs[1].addr = client->addr;
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[1].len = sizeof(regs);
|
||||
msgs[1].buf = regs;
|
||||
|
||||
err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (regs[0] & REG_SECONDS_OS) {
|
||||
/*
|
||||
* If the oscillator was stopped, try to clear the flag. Upon
|
||||
* power-up the flag is always set, but if we cannot clear it
|
||||
* the oscillator isn't running properly for some reason. The
|
||||
* sensible thing therefore is to return an error, signalling
|
||||
* that the clock cannot be assumed to be correct.
|
||||
*/
|
||||
|
||||
regs[0] &= ~REG_SECONDS_OS;
|
||||
|
||||
err = pcf8523_write(client, REG_SECONDS, regs[0]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = pcf8523_read(client, REG_SECONDS, ®s[0]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (regs[0] & REG_SECONDS_OS)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
tm->tm_sec = bcd2bin(regs[0] & 0x7f);
|
||||
tm->tm_min = bcd2bin(regs[1] & 0x7f);
|
||||
tm->tm_hour = bcd2bin(regs[2] & 0x3f);
|
||||
tm->tm_mday = bcd2bin(regs[3] & 0x3f);
|
||||
tm->tm_wday = regs[4] & 0x7;
|
||||
tm->tm_mon = bcd2bin(regs[5] & 0x1f);
|
||||
tm->tm_year = bcd2bin(regs[6]) + 100;
|
||||
|
||||
return rtc_valid_tm(tm);
|
||||
}
|
||||
|
||||
static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_msg msg;
|
||||
u8 regs[8];
|
||||
int err;
|
||||
|
||||
err = pcf8523_stop_rtc(client);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
regs[0] = REG_SECONDS;
|
||||
regs[1] = bin2bcd(tm->tm_sec);
|
||||
regs[2] = bin2bcd(tm->tm_min);
|
||||
regs[3] = bin2bcd(tm->tm_hour);
|
||||
regs[4] = bin2bcd(tm->tm_mday);
|
||||
regs[5] = tm->tm_wday;
|
||||
regs[6] = bin2bcd(tm->tm_mon);
|
||||
regs[7] = bin2bcd(tm->tm_year - 100);
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = 0;
|
||||
msg.len = sizeof(regs);
|
||||
msg.buf = regs;
|
||||
|
||||
err = i2c_transfer(client->adapter, &msg, 1);
|
||||
if (err < 0) {
|
||||
/*
|
||||
* If the time cannot be set, restart the RTC anyway. Note
|
||||
* that errors are ignored if the RTC cannot be started so
|
||||
* that we have a chance to propagate the original error.
|
||||
*/
|
||||
pcf8523_start_rtc(client);
|
||||
return err;
|
||||
}
|
||||
|
||||
return pcf8523_start_rtc(client);
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops pcf8523_rtc_ops = {
|
||||
.read_time = pcf8523_rtc_read_time,
|
||||
.set_time = pcf8523_rtc_set_time,
|
||||
};
|
||||
|
||||
static int pcf8523_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct pcf8523 *pcf;
|
||||
int err;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
return -ENODEV;
|
||||
|
||||
pcf = devm_kzalloc(&client->dev, sizeof(*pcf), GFP_KERNEL);
|
||||
if (!pcf)
|
||||
return -ENOMEM;
|
||||
|
||||
err = pcf8523_select_capacitance(client, true);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = pcf8523_set_pm(client, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
pcf->rtc = rtc_device_register(DRIVER_NAME, &client->dev,
|
||||
&pcf8523_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(pcf->rtc))
|
||||
return PTR_ERR(pcf->rtc);
|
||||
|
||||
i2c_set_clientdata(client, pcf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf8523_remove(struct i2c_client *client)
|
||||
{
|
||||
struct pcf8523 *pcf = i2c_get_clientdata(client);
|
||||
|
||||
rtc_device_unregister(pcf->rtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id pcf8523_id[] = {
|
||||
{ "pcf8523", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, pcf8523_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id pcf8523_of_match[] = {
|
||||
{ .compatible = "nxp,pcf8523" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pcf8523_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver pcf8523_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(pcf8523_of_match),
|
||||
},
|
||||
.probe = pcf8523_probe,
|
||||
.remove = pcf8523_remove,
|
||||
.id_table = pcf8523_id,
|
||||
};
|
||||
module_i2c_driver(pcf8523_driver);
|
||||
|
||||
MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
|
||||
MODULE_DESCRIPTION("NXP PCF8523 RTC driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -47,8 +47,6 @@ struct s3c_rtc_drv_data {
|
|||
/* I have yet to find an S3C implementation with more than one
|
||||
* of these rtc blocks in */
|
||||
|
||||
static struct resource *s3c_rtc_mem;
|
||||
|
||||
static struct clk *rtc_clk;
|
||||
static void __iomem *s3c_rtc_base;
|
||||
static int s3c_rtc_alarmno = NO_IRQ;
|
||||
|
@ -427,21 +425,13 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
|
|||
{
|
||||
struct rtc_device *rtc = platform_get_drvdata(dev);
|
||||
|
||||
free_irq(s3c_rtc_alarmno, rtc);
|
||||
free_irq(s3c_rtc_tickno, rtc);
|
||||
|
||||
platform_set_drvdata(dev, NULL);
|
||||
rtc_device_unregister(rtc);
|
||||
|
||||
s3c_rtc_setaie(&dev->dev, 0);
|
||||
|
||||
clk_put(rtc_clk);
|
||||
rtc_clk = NULL;
|
||||
|
||||
iounmap(s3c_rtc_base);
|
||||
release_resource(s3c_rtc_mem);
|
||||
kfree(s3c_rtc_mem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -496,28 +486,18 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
s3c_rtc_mem = request_mem_region(res->start, resource_size(res),
|
||||
pdev->name);
|
||||
|
||||
if (s3c_rtc_mem == NULL) {
|
||||
dev_err(&pdev->dev, "failed to reserve memory region\n");
|
||||
ret = -ENOENT;
|
||||
goto err_nores;
|
||||
}
|
||||
|
||||
s3c_rtc_base = ioremap(res->start, resource_size(res));
|
||||
s3c_rtc_base = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (s3c_rtc_base == NULL) {
|
||||
dev_err(&pdev->dev, "failed ioremap()\n");
|
||||
ret = -EINVAL;
|
||||
goto err_nomap;
|
||||
dev_err(&pdev->dev, "failed to ioremap memory region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rtc_clk = clk_get(&pdev->dev, "rtc");
|
||||
rtc_clk = devm_clk_get(&pdev->dev, "rtc");
|
||||
if (IS_ERR(rtc_clk)) {
|
||||
dev_err(&pdev->dev, "failed to find rtc clock source\n");
|
||||
ret = PTR_ERR(rtc_clk);
|
||||
rtc_clk = NULL;
|
||||
goto err_clk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
clk_enable(rtc_clk);
|
||||
|
@ -576,28 +556,24 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
|
|||
|
||||
s3c_rtc_setfreq(&pdev->dev, 1);
|
||||
|
||||
ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq,
|
||||
ret = devm_request_irq(&pdev->dev, s3c_rtc_alarmno, s3c_rtc_alarmirq,
|
||||
0, "s3c2410-rtc alarm", rtc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret);
|
||||
goto err_alarm_irq;
|
||||
}
|
||||
|
||||
ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq,
|
||||
ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq,
|
||||
0, "s3c2410-rtc tick", rtc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
|
||||
free_irq(s3c_rtc_alarmno, rtc);
|
||||
goto err_tick_irq;
|
||||
goto err_alarm_irq;
|
||||
}
|
||||
|
||||
clk_disable(rtc_clk);
|
||||
|
||||
return 0;
|
||||
|
||||
err_tick_irq:
|
||||
free_irq(s3c_rtc_alarmno, rtc);
|
||||
|
||||
err_alarm_irq:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
rtc_device_unregister(rtc);
|
||||
|
@ -605,15 +581,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
|
|||
err_nortc:
|
||||
s3c_rtc_enable(pdev, 0);
|
||||
clk_disable(rtc_clk);
|
||||
clk_put(rtc_clk);
|
||||
|
||||
err_clk:
|
||||
iounmap(s3c_rtc_base);
|
||||
|
||||
err_nomap:
|
||||
release_resource(s3c_rtc_mem);
|
||||
|
||||
err_nores:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -695,8 +663,6 @@ static const struct of_device_id s3c_rtc_dt_match[] = {
|
|||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
|
||||
#else
|
||||
#define s3c_rtc_dt_match NULL
|
||||
#endif
|
||||
|
||||
static struct platform_device_id s3c_rtc_driver_ids[] = {
|
||||
|
@ -727,7 +693,7 @@ static struct platform_driver s3c_rtc_driver = {
|
|||
.driver = {
|
||||
.name = "s3c-rtc",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = s3c_rtc_dt_match,
|
||||
.of_match_table = of_match_ptr(s3c_rtc_dt_match),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -363,35 +363,42 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "no resource defined\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
|
||||
dev_err(&pdev->dev, "rtc region already claimed\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
config = kzalloc(sizeof(*config), GFP_KERNEL);
|
||||
config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
|
||||
if (!config) {
|
||||
dev_err(&pdev->dev, "out of memory\n");
|
||||
status = -ENOMEM;
|
||||
goto err_release_region;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
config->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(config->clk)) {
|
||||
status = PTR_ERR(config->clk);
|
||||
goto err_kfree;
|
||||
/* alarm irqs */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "no update irq?\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
status = clk_enable(config->clk);
|
||||
if (status < 0)
|
||||
goto err_clk_put;
|
||||
status = devm_request_irq(&pdev->dev, irq, spear_rtc_irq, 0, pdev->name,
|
||||
config);
|
||||
if (status) {
|
||||
dev_err(&pdev->dev, "Alarm interrupt IRQ%d already claimed\n",
|
||||
irq);
|
||||
return status;
|
||||
}
|
||||
|
||||
config->ioaddr = ioremap(res->start, resource_size(res));
|
||||
config->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!config->ioaddr) {
|
||||
dev_err(&pdev->dev, "ioremap fail\n");
|
||||
status = -ENOMEM;
|
||||
goto err_disable_clock;
|
||||
dev_err(&pdev->dev, "request-ioremap fail\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
config->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(config->clk))
|
||||
return PTR_ERR(config->clk);
|
||||
|
||||
status = clk_prepare_enable(config->clk);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
spin_lock_init(&config->lock);
|
||||
platform_set_drvdata(pdev, config);
|
||||
|
||||
|
@ -401,42 +408,19 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
|
||||
PTR_ERR(config->rtc));
|
||||
status = PTR_ERR(config->rtc);
|
||||
goto err_iounmap;
|
||||
goto err_disable_clock;
|
||||
}
|
||||
|
||||
/* alarm irqs */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "no update irq?\n");
|
||||
status = irq;
|
||||
goto err_clear_platdata;
|
||||
}
|
||||
|
||||
status = request_irq(irq, spear_rtc_irq, 0, pdev->name, config);
|
||||
if (status) {
|
||||
dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \
|
||||
claimed\n", irq);
|
||||
goto err_clear_platdata;
|
||||
}
|
||||
config->rtc->uie_unsupported = 1;
|
||||
|
||||
if (!device_can_wakeup(&pdev->dev))
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
err_clear_platdata:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
rtc_device_unregister(config->rtc);
|
||||
err_iounmap:
|
||||
iounmap(config->ioaddr);
|
||||
err_disable_clock:
|
||||
clk_disable(config->clk);
|
||||
err_clk_put:
|
||||
clk_put(config->clk);
|
||||
err_kfree:
|
||||
kfree(config);
|
||||
err_release_region:
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
clk_disable_unprepare(config->clk);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -444,24 +428,11 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
|
|||
static int __devexit spear_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct spear_rtc_config *config = platform_get_drvdata(pdev);
|
||||
int irq;
|
||||
struct resource *res;
|
||||
|
||||
/* leave rtc running, but disable irqs */
|
||||
spear_rtc_disable_interrupt(config);
|
||||
device_init_wakeup(&pdev->dev, 0);
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq)
|
||||
free_irq(irq, pdev);
|
||||
clk_disable(config->clk);
|
||||
clk_put(config->clk);
|
||||
iounmap(config->ioaddr);
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res)
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
rtc_device_unregister(config->rtc);
|
||||
kfree(config);
|
||||
spear_rtc_disable_interrupt(config);
|
||||
clk_disable_unprepare(config->clk);
|
||||
device_init_wakeup(&pdev->dev, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -152,24 +152,24 @@ static int __init test_init(void)
|
|||
|
||||
if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto exit_free_test0;
|
||||
goto exit_put_test0;
|
||||
}
|
||||
|
||||
if ((err = platform_device_add(test0)))
|
||||
goto exit_free_test1;
|
||||
goto exit_put_test1;
|
||||
|
||||
if ((err = platform_device_add(test1)))
|
||||
goto exit_device_unregister;
|
||||
goto exit_del_test0;
|
||||
|
||||
return 0;
|
||||
|
||||
exit_device_unregister:
|
||||
platform_device_unregister(test0);
|
||||
exit_del_test0:
|
||||
platform_device_del(test0);
|
||||
|
||||
exit_free_test1:
|
||||
exit_put_test1:
|
||||
platform_device_put(test1);
|
||||
|
||||
exit_free_test0:
|
||||
exit_put_test0:
|
||||
platform_device_put(test0);
|
||||
|
||||
exit_driver_unregister:
|
||||
|
|
|
@ -247,6 +247,13 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
|
||||
dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n");
|
||||
|
||||
/* Enable RTC digital power domain */
|
||||
ret = regmap_update_bits(tps65910->regmap, TPS65910_DEVCTRL,
|
||||
DEVCTRL_RTC_PWDN_MASK, 0 << DEVCTRL_RTC_PWDN_SHIFT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
rtc_reg = TPS65910_RTC_CTRL_STOP_RTC;
|
||||
ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg);
|
||||
if (ret < 0)
|
||||
|
@ -261,7 +268,7 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev)
|
|||
|
||||
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||
tps65910_rtc_interrupt, IRQF_TRIGGER_LOW,
|
||||
"rtc-tps65910", &pdev->dev);
|
||||
dev_name(&pdev->dev), &pdev->dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "IRQ is not free.\n");
|
||||
return ret;
|
||||
|
|
|
@ -210,7 +210,8 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
|
|||
struct vt8500_rtc *vt8500_rtc;
|
||||
int ret;
|
||||
|
||||
vt8500_rtc = kzalloc(sizeof(struct vt8500_rtc), GFP_KERNEL);
|
||||
vt8500_rtc = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct vt8500_rtc), GFP_KERNEL);
|
||||
if (!vt8500_rtc)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -220,15 +221,13 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
|
|||
vt8500_rtc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!vt8500_rtc->res) {
|
||||
dev_err(&pdev->dev, "No I/O memory resource defined\n");
|
||||
ret = -ENXIO;
|
||||
goto err_free;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0);
|
||||
if (vt8500_rtc->irq_alarm < 0) {
|
||||
dev_err(&pdev->dev, "No alarm IRQ resource defined\n");
|
||||
ret = -ENXIO;
|
||||
goto err_free;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start,
|
||||
|
@ -236,8 +235,7 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
|
|||
"vt8500-rtc");
|
||||
if (vt8500_rtc->res == NULL) {
|
||||
dev_err(&pdev->dev, "failed to request I/O memory\n");
|
||||
ret = -EBUSY;
|
||||
goto err_free;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start,
|
||||
|
@ -278,8 +276,6 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
|
|||
err_release:
|
||||
release_mem_region(vt8500_rtc->res->start,
|
||||
resource_size(vt8500_rtc->res));
|
||||
err_free:
|
||||
kfree(vt8500_rtc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -297,7 +293,6 @@ static int __devexit vt8500_rtc_remove(struct platform_device *pdev)
|
|||
release_mem_region(vt8500_rtc->res->start,
|
||||
resource_size(vt8500_rtc->res));
|
||||
|
||||
kfree(vt8500_rtc);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2144,7 +2144,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip)
|
|||
*/
|
||||
port_id = fip->port_id;
|
||||
if (fip->probe_tries)
|
||||
port_id = prandom32(&fip->rnd_state) & 0xffff;
|
||||
port_id = prandom_u32_state(&fip->rnd_state) & 0xffff;
|
||||
else if (!port_id)
|
||||
port_id = fip->lp->wwpn & 0xffff;
|
||||
if (!port_id || port_id == 0xffff)
|
||||
|
@ -2169,7 +2169,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip)
|
|||
static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
|
||||
{
|
||||
fip->probe_tries = 0;
|
||||
prandom32_seed(&fip->rnd_state, fip->lp->wwpn);
|
||||
prandom_seed_state(&fip->rnd_state, fip->lp->wwpn);
|
||||
fcoe_ctlr_vn_restart(fip);
|
||||
}
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
|
|||
/* best case is 32bit-aligned source address */
|
||||
if ((0x02 & (unsigned long) src) == 0) {
|
||||
if (len >= 4) {
|
||||
writesl(fifo, src + index, len >> 2);
|
||||
iowrite32_rep(fifo, src + index, len >> 2);
|
||||
index += len & ~0x03;
|
||||
}
|
||||
if (len & 0x02) {
|
||||
|
@ -260,7 +260,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
|
|||
}
|
||||
} else {
|
||||
if (len >= 2) {
|
||||
writesw(fifo, src + index, len >> 1);
|
||||
iowrite16_rep(fifo, src + index, len >> 1);
|
||||
index += len & ~0x01;
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
|
|||
musb_writeb(fifo, 0, src[index]);
|
||||
} else {
|
||||
/* byte aligned */
|
||||
writesb(fifo, src, len);
|
||||
iowrite8_rep(fifo, src, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
|
|||
/* best case is 32bit-aligned destination address */
|
||||
if ((0x02 & (unsigned long) dst) == 0) {
|
||||
if (len >= 4) {
|
||||
readsl(fifo, dst, len >> 2);
|
||||
ioread32_rep(fifo, dst, len >> 2);
|
||||
index = len & ~0x03;
|
||||
}
|
||||
if (len & 0x02) {
|
||||
|
@ -303,7 +303,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
|
|||
}
|
||||
} else {
|
||||
if (len >= 2) {
|
||||
readsw(fifo, dst, len >> 1);
|
||||
ioread16_rep(fifo, dst, len >> 1);
|
||||
index = len & ~0x01;
|
||||
}
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
|
|||
dst[index] = musb_readb(fifo, 0);
|
||||
} else {
|
||||
/* byte aligned */
|
||||
readsb(fifo, dst, len);
|
||||
ioread8_rep(fifo, dst, len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,27 +37,6 @@
|
|||
|
||||
#include <linux/io.h>
|
||||
|
||||
#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
|
||||
&& !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
|
||||
&& !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) \
|
||||
&& !defined(CONFIG_MIPS) && !defined(CONFIG_M68K) \
|
||||
&& !defined(CONFIG_XTENSA)
|
||||
static inline void readsl(const void __iomem *addr, void *buf, int len)
|
||||
{ insl((unsigned long)addr, buf, len); }
|
||||
static inline void readsw(const void __iomem *addr, void *buf, int len)
|
||||
{ insw((unsigned long)addr, buf, len); }
|
||||
static inline void readsb(const void __iomem *addr, void *buf, int len)
|
||||
{ insb((unsigned long)addr, buf, len); }
|
||||
|
||||
static inline void writesl(const void __iomem *addr, const void *buf, int len)
|
||||
{ outsl((unsigned long)addr, buf, len); }
|
||||
static inline void writesw(const void __iomem *addr, const void *buf, int len)
|
||||
{ outsw((unsigned long)addr, buf, len); }
|
||||
static inline void writesb(const void __iomem *addr, const void *buf, int len)
|
||||
{ outsb((unsigned long)addr, buf, len); }
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_BLACKFIN
|
||||
|
||||
/* NOTE: these offsets are all in bytes */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/prefetch.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/usb/nop-usb-xceiv.h>
|
||||
|
@ -198,7 +199,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf)
|
|||
/* Best case is 32bit-aligned destination address */
|
||||
if ((0x02 & (unsigned long) buf) == 0) {
|
||||
if (len >= 4) {
|
||||
writesl(fifo, buf, len >> 2);
|
||||
iowrite32_rep(fifo, buf, len >> 2);
|
||||
buf += (len & ~0x03);
|
||||
len &= 0x03;
|
||||
}
|
||||
|
@ -245,7 +246,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf)
|
|||
/* Best case is 32bit-aligned destination address */
|
||||
if ((0x02 & (unsigned long) buf) == 0) {
|
||||
if (len >= 4) {
|
||||
readsl(fifo, buf, len >> 2);
|
||||
ioread32_rep(fifo, buf, len >> 2);
|
||||
buf += (len & ~0x03);
|
||||
len &= 0x03;
|
||||
}
|
||||
|
|
|
@ -117,8 +117,8 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
|
|||
data->current_brightness = value;
|
||||
return 0;
|
||||
out:
|
||||
dev_dbg(chip->dev, "set brightness %d failure with return "
|
||||
"value:%d\n", value, ret);
|
||||
dev_dbg(chip->dev, "set brightness %d failure with return value: %d\n",
|
||||
value, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -208,22 +208,19 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
|
|||
res = platform_get_resource_byname(pdev, IORESOURCE_REG, "duty cycle");
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "No REG resource for duty cycle\n");
|
||||
ret = -ENXIO;
|
||||
goto out;
|
||||
return -ENXIO;
|
||||
}
|
||||
data->reg_duty_cycle = res->start;
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_REG, "always on");
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "No REG resorce for always on\n");
|
||||
ret = -ENXIO;
|
||||
goto out;
|
||||
return -ENXIO;
|
||||
}
|
||||
data->reg_always_on = res->start;
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_REG, "current");
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "No REG resource for current\n");
|
||||
ret = -ENXIO;
|
||||
goto out;
|
||||
return -ENXIO;
|
||||
}
|
||||
data->reg_current = res->start;
|
||||
|
||||
|
@ -231,8 +228,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
|
|||
sprintf(name, "backlight-%d", pdev->id);
|
||||
data->port = pdev->id;
|
||||
data->chip = chip;
|
||||
data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
|
||||
: chip->companion;
|
||||
data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
|
||||
data->current_brightness = MAX_BRIGHTNESS;
|
||||
if (pm860x_backlight_dt_init(pdev, data, name)) {
|
||||
if (pdata) {
|
||||
|
@ -263,8 +259,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
out_brt:
|
||||
backlight_device_unregister(bl);
|
||||
out:
|
||||
devm_kfree(&pdev->dev, data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,10 +106,9 @@ static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
|
|||
pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD,
|
||||
pwmbl->pdata->pwm_compare_max);
|
||||
|
||||
dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver "
|
||||
"(%lu Hz)\n", pwmbl->pwmc.mck /
|
||||
pwmbl->pdata->pwm_compare_max /
|
||||
(1 << prescale));
|
||||
dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver (%lu Hz)\n",
|
||||
pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max /
|
||||
(1 << prescale));
|
||||
|
||||
return pwm_channel_enable(&pwmbl->pwmc);
|
||||
}
|
||||
|
|
|
@ -370,6 +370,35 @@ void backlight_device_unregister(struct backlight_device *bd)
|
|||
}
|
||||
EXPORT_SYMBOL(backlight_device_unregister);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int of_parent_match(struct device *dev, void *data)
|
||||
{
|
||||
return dev->parent && dev->parent->of_node == data;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_find_backlight_by_node() - find backlight device by device-tree node
|
||||
* @node: device-tree node of the backlight device
|
||||
*
|
||||
* Returns a pointer to the backlight device corresponding to the given DT
|
||||
* node or NULL if no such backlight device exists or if the device hasn't
|
||||
* been probed yet.
|
||||
*
|
||||
* This function obtains a reference on the backlight device and it is the
|
||||
* caller's responsibility to drop the reference by calling put_device() on
|
||||
* the backlight device's .dev field.
|
||||
*/
|
||||
struct backlight_device *of_find_backlight_by_node(struct device_node *node)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = class_find_device(backlight_class, NULL, node, of_parent_match);
|
||||
|
||||
return dev ? to_backlight_device(dev) : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_backlight_by_node);
|
||||
#endif
|
||||
|
||||
static void __exit backlight_class_exit(void)
|
||||
{
|
||||
class_destroy(backlight_class);
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* Based on Sharp's 2.4 Backlight Driver
|
||||
*
|
||||
* Copyright (c) 2008 Marvell International Ltd.
|
||||
* Converted to SPI device based LCD/Backlight device driver
|
||||
* by Eric Miao <eric.miao@marvell.com>
|
||||
* Converted to SPI device based LCD/Backlight device driver
|
||||
* by Eric Miao <eric.miao@marvell.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -192,7 +192,7 @@ static void lcdtg_set_phadadj(struct corgi_lcd *lcd, int mode)
|
|||
{
|
||||
int adj;
|
||||
|
||||
switch(mode) {
|
||||
switch (mode) {
|
||||
case CORGI_LCD_MODE_VGA:
|
||||
/* Setting for VGA */
|
||||
adj = sharpsl_param.phadadj;
|
||||
|
@ -409,10 +409,10 @@ static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity)
|
|||
cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted;
|
||||
|
||||
if (gpio_is_valid(lcd->gpio_backlight_cont))
|
||||
gpio_set_value(lcd->gpio_backlight_cont, cont);
|
||||
gpio_set_value_cansleep(lcd->gpio_backlight_cont, cont);
|
||||
|
||||
if (gpio_is_valid(lcd->gpio_backlight_on))
|
||||
gpio_set_value(lcd->gpio_backlight_on, intensity);
|
||||
gpio_set_value_cansleep(lcd->gpio_backlight_on, intensity);
|
||||
|
||||
if (lcd->kick_battery)
|
||||
lcd->kick_battery();
|
||||
|
@ -495,8 +495,9 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd,
|
|||
err = devm_gpio_request(&spi->dev, pdata->gpio_backlight_on,
|
||||
"BL_ON");
|
||||
if (err) {
|
||||
dev_err(&spi->dev, "failed to request GPIO%d for "
|
||||
"backlight_on\n", pdata->gpio_backlight_on);
|
||||
dev_err(&spi->dev,
|
||||
"failed to request GPIO%d for backlight_on\n",
|
||||
pdata->gpio_backlight_on);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -508,8 +509,9 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd,
|
|||
err = devm_gpio_request(&spi->dev, pdata->gpio_backlight_cont,
|
||||
"BL_CONT");
|
||||
if (err) {
|
||||
dev_err(&spi->dev, "failed to request GPIO%d for "
|
||||
"backlight_cont\n", pdata->gpio_backlight_cont);
|
||||
dev_err(&spi->dev,
|
||||
"failed to request GPIO%d for backlight_cont\n",
|
||||
pdata->gpio_backlight_cont);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
* Backlight driver for Dialog Semiconductor DA9030/DA9034
|
||||
*
|
||||
* Copyright (C) 2008 Compulab, Ltd.
|
||||
* Mike Rapoport <mike@compulab.co.il>
|
||||
* Mike Rapoport <mike@compulab.co.il>
|
||||
*
|
||||
* Copyright (C) 2006-2008 Marvell International Ltd.
|
||||
* Eric Miao <eric.miao@marvell.com>
|
||||
* Eric Miao <eric.miao@marvell.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -164,15 +164,14 @@ static int da903x_backlight_remove(struct platform_device *pdev)
|
|||
#ifdef CONFIG_PM
|
||||
static int da903x_backlight_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct backlight_device *bl = platform_get_drvdata(pdev);
|
||||
struct backlight_device *bl = dev_get_drvdata(dev);
|
||||
|
||||
return da903x_backlight_set(bl, 0);
|
||||
}
|
||||
|
||||
static int da903x_backlight_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct backlight_device *bl = platform_get_drvdata(pdev);
|
||||
struct backlight_device *bl = dev_get_drvdata(dev);
|
||||
|
||||
backlight_update_status(bl);
|
||||
return 0;
|
||||
|
@ -199,7 +198,7 @@ static struct platform_driver da903x_backlight_driver = {
|
|||
module_platform_driver(da903x_backlight_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034");
|
||||
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
|
||||
"Mike Rapoport <mike@compulab.co.il>");
|
||||
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
|
||||
MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:da903x-backlight");
|
||||
|
|
|
@ -34,7 +34,7 @@ enum {
|
|||
DA9052_TYPE_WLED3,
|
||||
};
|
||||
|
||||
static unsigned char wled_bank[] = {
|
||||
static const unsigned char wled_bank[] = {
|
||||
DA9052_LED1_CONF_REG,
|
||||
DA9052_LED2_CONF_REG,
|
||||
DA9052_LED3_CONF_REG,
|
||||
|
|
|
@ -97,8 +97,8 @@ static int genericbl_probe(struct platform_device *pdev)
|
|||
props.max_brightness = machinfo->max_intensity;
|
||||
bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
|
||||
&props);
|
||||
if (IS_ERR (bd))
|
||||
return PTR_ERR (bd);
|
||||
if (IS_ERR(bd))
|
||||
return PTR_ERR(bd);
|
||||
|
||||
platform_set_drvdata(pdev, bd);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#define HP680_DEFAULT_INTENSITY 10
|
||||
|
||||
static int hp680bl_suspended;
|
||||
static int current_intensity = 0;
|
||||
static int current_intensity;
|
||||
static DEFINE_SPINLOCK(bl_lock);
|
||||
|
||||
static void hp680bl_send_intensity(struct backlight_device *bd)
|
||||
|
@ -168,7 +168,7 @@ static int __init hp680bl_init(void)
|
|||
static void __exit hp680bl_exit(void)
|
||||
{
|
||||
platform_device_unregister(hp680bl_device);
|
||||
platform_driver_unregister(&hp680bl_driver);
|
||||
platform_driver_unregister(&hp680bl_driver);
|
||||
}
|
||||
|
||||
module_init(hp680bl_init);
|
||||
|
|
|
@ -45,7 +45,7 @@ static inline int ili9320_write_spi(struct ili9320 *ili,
|
|||
/* second message is the data to transfer */
|
||||
|
||||
data[0] = spi->id | ILI9320_SPI_DATA | ILI9320_SPI_WRITE;
|
||||
data[1] = value >> 8;
|
||||
data[1] = value >> 8;
|
||||
data[2] = value;
|
||||
|
||||
return spi_sync(spi->dev, &spi->message);
|
||||
|
@ -56,11 +56,10 @@ int ili9320_write(struct ili9320 *ili, unsigned int reg, unsigned int value)
|
|||
dev_dbg(ili->dev, "write: reg=%02x, val=%04x\n", reg, value);
|
||||
return ili->write(ili, reg, value);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ili9320_write);
|
||||
|
||||
int ili9320_write_regs(struct ili9320 *ili,
|
||||
struct ili9320_reg *values,
|
||||
const struct ili9320_reg *values,
|
||||
int nr_values)
|
||||
{
|
||||
int index;
|
||||
|
@ -74,7 +73,6 @@ int ili9320_write_regs(struct ili9320 *ili,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ili9320_write_regs);
|
||||
|
||||
static void ili9320_reset(struct ili9320 *lcd)
|
||||
|
@ -260,7 +258,6 @@ int ili9320_probe_spi(struct spi_device *spi,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ili9320_probe_spi);
|
||||
|
||||
int ili9320_remove(struct ili9320 *ili)
|
||||
|
@ -271,7 +268,6 @@ int ili9320_remove(struct ili9320 *ili)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ili9320_remove);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -296,20 +292,17 @@ int ili9320_suspend(struct ili9320 *lcd, pm_message_t state)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ili9320_suspend);
|
||||
|
||||
int ili9320_resume(struct ili9320 *lcd)
|
||||
{
|
||||
dev_info(lcd->dev, "resuming from power state %d\n", lcd->power);
|
||||
|
||||
if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
|
||||
if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP)
|
||||
ili9320_write(lcd, ILI9320_POWER1, 0x00);
|
||||
}
|
||||
|
||||
return ili9320_power(lcd, FB_BLANK_UNBLANK);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ili9320_resume);
|
||||
#endif
|
||||
|
||||
|
@ -318,7 +311,6 @@ void ili9320_shutdown(struct ili9320 *lcd)
|
|||
{
|
||||
ili9320_power(lcd, FB_BLANK_POWERDOWN);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ili9320_shutdown);
|
||||
|
||||
MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
|
||||
|
|
|
@ -63,7 +63,7 @@ extern int ili9320_write(struct ili9320 *ili,
|
|||
unsigned int reg, unsigned int value);
|
||||
|
||||
extern int ili9320_write_regs(struct ili9320 *ili,
|
||||
struct ili9320_reg *values,
|
||||
const struct ili9320_reg *values,
|
||||
int nr_values);
|
||||
|
||||
/* Device probe */
|
||||
|
|
|
@ -48,7 +48,7 @@ static int jornada_bl_get_brightness(struct backlight_device *bd)
|
|||
|
||||
jornada_ssp_end();
|
||||
|
||||
return (BL_MAX_BRIGHT - ret);
|
||||
return BL_MAX_BRIGHT - ret;
|
||||
}
|
||||
|
||||
static int jornada_bl_update_status(struct backlight_device *bd)
|
||||
|
@ -77,18 +77,23 @@ static int jornada_bl_update_status(struct backlight_device *bd)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* at this point we expect that the mcu has accepted
|
||||
our command and is waiting for our new value
|
||||
please note that maximum brightness is 255,
|
||||
but due to physical layout it is equal to 0, so we simply
|
||||
invert the value (MAX VALUE - NEW VALUE). */
|
||||
if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) != TXDUMMY) {
|
||||
/*
|
||||
* at this point we expect that the mcu has accepted
|
||||
* our command and is waiting for our new value
|
||||
* please note that maximum brightness is 255,
|
||||
* but due to physical layout it is equal to 0, so we simply
|
||||
* invert the value (MAX VALUE - NEW VALUE).
|
||||
*/
|
||||
if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness)
|
||||
!= TXDUMMY) {
|
||||
pr_err("set brightness failed\n");
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* If infact we get an TXDUMMY as output we are happy and dont
|
||||
make any further comments about it */
|
||||
/*
|
||||
* If infact we get an TXDUMMY as output we are happy and dont
|
||||
* make any further comments about it
|
||||
*/
|
||||
out:
|
||||
jornada_ssp_end();
|
||||
|
||||
|
@ -121,9 +126,11 @@ static int jornada_bl_probe(struct platform_device *pdev)
|
|||
|
||||
bd->props.power = FB_BLANK_UNBLANK;
|
||||
bd->props.brightness = BL_DEF_BRIGHT;
|
||||
/* note. make sure max brightness is set otherwise
|
||||
you will get seemingly non-related errors when
|
||||
trying to change brightness */
|
||||
/*
|
||||
* note. make sure max brightness is set otherwise
|
||||
* you will get seemingly non-related errors when
|
||||
* trying to change brightness
|
||||
*/
|
||||
jornada_bl_update_status(bd);
|
||||
|
||||
platform_set_drvdata(pdev, bd);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
|
||||
* Inspired by Marek Vasut work in l4f00242t03.c
|
||||
* Inspired by Marek Vasut work in l4f00242t03.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -33,7 +33,6 @@ struct l4f00242t03_priv {
|
|||
struct regulator *core_reg;
|
||||
};
|
||||
|
||||
|
||||
static void l4f00242t03_reset(unsigned int gpio)
|
||||
{
|
||||
pr_debug("l4f00242t03_reset.\n");
|
||||
|
|
|
@ -108,7 +108,7 @@ static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr,
|
|||
static ssize_t lcd_store_power(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int rc = -ENXIO;
|
||||
int rc;
|
||||
struct lcd_device *ld = to_lcd_device(dev);
|
||||
unsigned long power;
|
||||
|
||||
|
@ -116,6 +116,8 @@ static ssize_t lcd_store_power(struct device *dev,
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = -ENXIO;
|
||||
|
||||
mutex_lock(&ld->ops_lock);
|
||||
if (ld->ops && ld->ops->set_power) {
|
||||
pr_debug("set power to %lu\n", power);
|
||||
|
@ -144,7 +146,7 @@ static ssize_t lcd_show_contrast(struct device *dev,
|
|||
static ssize_t lcd_store_contrast(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int rc = -ENXIO;
|
||||
int rc;
|
||||
struct lcd_device *ld = to_lcd_device(dev);
|
||||
unsigned long contrast;
|
||||
|
||||
|
@ -152,6 +154,8 @@ static ssize_t lcd_store_contrast(struct device *dev,
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = -ENXIO;
|
||||
|
||||
mutex_lock(&ld->ops_lock);
|
||||
if (ld->ops && ld->ops->set_contrast) {
|
||||
pr_debug("set contrast to %lu\n", contrast);
|
||||
|
|
|
@ -37,7 +37,7 @@ enum lm3630_leds {
|
|||
BLED_2
|
||||
};
|
||||
|
||||
static const char *bled_name[] = {
|
||||
static const char * const bled_name[] = {
|
||||
[BLED_ALL] = "lm3630_bled", /*Bank1 controls all string */
|
||||
[BLED_1] = "lm3630_bled1", /*Bank1 controls bled1 */
|
||||
[BLED_2] = "lm3630_bled2", /*Bank1 or 2 controls bled2 */
|
||||
|
|
|
@ -214,7 +214,7 @@ static ssize_t lm3639_bled_mode_store(struct device *dev,
|
|||
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(bled_mode, 0666, NULL, lm3639_bled_mode_store);
|
||||
static DEVICE_ATTR(bled_mode, S_IWUSR, NULL, lm3639_bled_mode_store);
|
||||
|
||||
/* torch */
|
||||
static void lm3639_torch_brightness_set(struct led_classdev *cdev,
|
||||
|
|
|
@ -31,7 +31,7 @@ struct lms283gf05_seq {
|
|||
};
|
||||
|
||||
/* Magic sequences supplied by manufacturer, for details refer to datasheet */
|
||||
static struct lms283gf05_seq disp_initseq[] = {
|
||||
static const struct lms283gf05_seq disp_initseq[] = {
|
||||
/* REG, VALUE, DELAY */
|
||||
{ 0x07, 0x0000, 0 },
|
||||
{ 0x13, 0x0000, 10 },
|
||||
|
@ -78,7 +78,7 @@ static struct lms283gf05_seq disp_initseq[] = {
|
|||
{ 0x22, 0x0000, 0 }
|
||||
};
|
||||
|
||||
static struct lms283gf05_seq disp_pdwnseq[] = {
|
||||
static const struct lms283gf05_seq disp_pdwnseq[] = {
|
||||
{ 0x07, 0x0016, 30 },
|
||||
|
||||
{ 0x07, 0x0004, 0 },
|
||||
|
@ -104,7 +104,7 @@ static void lms283gf05_reset(unsigned long gpio, bool inverted)
|
|||
}
|
||||
|
||||
static void lms283gf05_toggle(struct spi_device *spi,
|
||||
struct lms283gf05_seq *seq, int sz)
|
||||
const struct lms283gf05_seq *seq, int sz)
|
||||
{
|
||||
char buf[3];
|
||||
int i;
|
||||
|
@ -158,13 +158,10 @@ static int lms283gf05_probe(struct spi_device *spi)
|
|||
int ret = 0;
|
||||
|
||||
if (pdata != NULL) {
|
||||
ret = devm_gpio_request(&spi->dev, pdata->reset_gpio,
|
||||
"LMS285GF05 RESET");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = gpio_direction_output(pdata->reset_gpio,
|
||||
!pdata->reset_inverted);
|
||||
ret = devm_gpio_request_one(&spi->dev, pdata->reset_gpio,
|
||||
GPIOF_DIR_OUT | (!pdata->reset_inverted ?
|
||||
GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
|
||||
"LMS285GF05 RESET");
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/backlight.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_data/lp855x.h>
|
||||
#include <linux/pwm.h>
|
||||
|
||||
/* Registers */
|
||||
#define BRIGHTNESS_CTRL 0x00
|
||||
|
@ -34,22 +35,19 @@ struct lp855x {
|
|||
struct i2c_client *client;
|
||||
struct backlight_device *bl;
|
||||
struct device *dev;
|
||||
struct mutex xfer_lock;
|
||||
struct lp855x_platform_data *pdata;
|
||||
struct pwm_device *pwm;
|
||||
};
|
||||
|
||||
static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&lp->xfer_lock);
|
||||
ret = i2c_smbus_read_byte_data(lp->client, reg);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&lp->xfer_lock);
|
||||
dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
|
||||
return ret;
|
||||
}
|
||||
mutex_unlock(&lp->xfer_lock);
|
||||
|
||||
*data = (u8)ret;
|
||||
return 0;
|
||||
|
@ -57,13 +55,7 @@ static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
|
|||
|
||||
static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&lp->xfer_lock);
|
||||
ret = i2c_smbus_write_byte_data(lp->client, reg, data);
|
||||
mutex_unlock(&lp->xfer_lock);
|
||||
|
||||
return ret;
|
||||
return i2c_smbus_write_byte_data(lp->client, reg, data);
|
||||
}
|
||||
|
||||
static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
|
||||
|
@ -121,6 +113,28 @@ static int lp855x_init_registers(struct lp855x *lp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br)
|
||||
{
|
||||
unsigned int period = lp->pdata->period_ns;
|
||||
unsigned int duty = br * period / max_br;
|
||||
struct pwm_device *pwm;
|
||||
|
||||
/* request pwm device with the consumer name */
|
||||
if (!lp->pwm) {
|
||||
pwm = devm_pwm_get(lp->dev, lp->chipname);
|
||||
if (IS_ERR(pwm))
|
||||
return;
|
||||
|
||||
lp->pwm = pwm;
|
||||
}
|
||||
|
||||
pwm_config(lp->pwm, duty, period);
|
||||
if (duty)
|
||||
pwm_enable(lp->pwm);
|
||||
else
|
||||
pwm_disable(lp->pwm);
|
||||
}
|
||||
|
||||
static int lp855x_bl_update_status(struct backlight_device *bl)
|
||||
{
|
||||
struct lp855x *lp = bl_get_data(bl);
|
||||
|
@ -130,12 +144,10 @@ static int lp855x_bl_update_status(struct backlight_device *bl)
|
|||
bl->props.brightness = 0;
|
||||
|
||||
if (mode == PWM_BASED) {
|
||||
struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
|
||||
int br = bl->props.brightness;
|
||||
int max_br = bl->props.max_brightness;
|
||||
|
||||
if (pd->pwm_set_intensity)
|
||||
pd->pwm_set_intensity(br, max_br);
|
||||
lp855x_pwm_ctrl(lp, br, max_br);
|
||||
|
||||
} else if (mode == REGISTER_BASED) {
|
||||
u8 val = bl->props.brightness;
|
||||
|
@ -150,14 +162,7 @@ static int lp855x_bl_get_brightness(struct backlight_device *bl)
|
|||
struct lp855x *lp = bl_get_data(bl);
|
||||
enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
|
||||
|
||||
if (mode == PWM_BASED) {
|
||||
struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
|
||||
int max_br = bl->props.max_brightness;
|
||||
|
||||
if (pd->pwm_get_intensity)
|
||||
bl->props.brightness = pd->pwm_get_intensity(max_br);
|
||||
|
||||
} else if (mode == REGISTER_BASED) {
|
||||
if (mode == REGISTER_BASED) {
|
||||
u8 val = 0;
|
||||
|
||||
lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
|
||||
|
@ -266,8 +271,6 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
|||
lp->chip_id = id->driver_data;
|
||||
i2c_set_clientdata(cl, lp);
|
||||
|
||||
mutex_init(&lp->xfer_lock);
|
||||
|
||||
ret = lp855x_init_registers(lp);
|
||||
if (ret) {
|
||||
dev_err(lp->dev, "i2c communication err: %d", ret);
|
||||
|
|
|
@ -120,15 +120,13 @@ static int max8925_backlight_probe(struct platform_device *pdev)
|
|||
res = platform_get_resource(pdev, IORESOURCE_REG, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "No REG resource for mode control!\n");
|
||||
ret = -ENXIO;
|
||||
goto out;
|
||||
return -ENXIO;
|
||||
}
|
||||
data->reg_mode_cntl = res->start;
|
||||
res = platform_get_resource(pdev, IORESOURCE_REG, 1);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "No REG resource for control!\n");
|
||||
ret = -ENXIO;
|
||||
goto out;
|
||||
return -ENXIO;
|
||||
}
|
||||
data->reg_cntl = res->start;
|
||||
|
||||
|
@ -142,8 +140,7 @@ static int max8925_backlight_probe(struct platform_device *pdev)
|
|||
&max8925_backlight_ops, &props);
|
||||
if (IS_ERR(bl)) {
|
||||
dev_err(&pdev->dev, "failed to register backlight\n");
|
||||
ret = PTR_ERR(bl);
|
||||
goto out;
|
||||
return PTR_ERR(bl);
|
||||
}
|
||||
bl->props.brightness = MAX_BRIGHTNESS;
|
||||
|
||||
|
@ -166,8 +163,6 @@ static int max8925_backlight_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
out_brt:
|
||||
backlight_device_unregister(bl);
|
||||
out:
|
||||
devm_kfree(&pdev->dev, data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,12 +42,12 @@ struct omap_backlight {
|
|||
struct omap_backlight_config *pdata;
|
||||
};
|
||||
|
||||
static void inline omapbl_send_intensity(int intensity)
|
||||
static inline void omapbl_send_intensity(int intensity)
|
||||
{
|
||||
omap_writeb(intensity, OMAP_PWL_ENABLE);
|
||||
}
|
||||
|
||||
static void inline omapbl_send_enable(int enable)
|
||||
static inline void omapbl_send_enable(int enable)
|
||||
{
|
||||
omap_writeb(enable, OMAP_PWL_CLK_ENABLE);
|
||||
}
|
||||
|
|
|
@ -71,8 +71,7 @@ static int pandora_backlight_update_status(struct backlight_device *bl)
|
|||
* set PWM duty cycle to max. TPS61161 seems to use this
|
||||
* to calibrate it's PWM sensitivity when it starts.
|
||||
*/
|
||||
twl_i2c_write_u8(TWL4030_MODULE_PWM0, MAX_VALUE,
|
||||
TWL_PWM0_OFF);
|
||||
twl_i2c_write_u8(TWL_MODULE_PWM, MAX_VALUE, TWL_PWM0_OFF);
|
||||
|
||||
/* first enable clock, then PWM0 out */
|
||||
twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
|
||||
|
@ -90,8 +89,7 @@ static int pandora_backlight_update_status(struct backlight_device *bl)
|
|||
usleep_range(2000, 10000);
|
||||
}
|
||||
|
||||
twl_i2c_write_u8(TWL4030_MODULE_PWM0, MIN_VALUE + brightness,
|
||||
TWL_PWM0_OFF);
|
||||
twl_i2c_write_u8(TWL_MODULE_PWM, MIN_VALUE + brightness, TWL_PWM0_OFF);
|
||||
|
||||
done:
|
||||
if (brightness != 0)
|
||||
|
@ -132,7 +130,7 @@ static int pandora_backlight_probe(struct platform_device *pdev)
|
|||
platform_set_drvdata(pdev, bl);
|
||||
|
||||
/* 64 cycle period, ON position 0 */
|
||||
twl_i2c_write_u8(TWL4030_MODULE_PWM0, 0x80, TWL_PWM0_ON);
|
||||
twl_i2c_write_u8(TWL_MODULE_PWM, 0x80, TWL_PWM0_ON);
|
||||
|
||||
bl->props.state |= PANDORABL_WAS_OFF;
|
||||
bl->props.brightness = MAX_USER_VALUE;
|
||||
|
|
|
@ -52,7 +52,7 @@ int pcf50633_bl_set_brightness_limit(struct pcf50633 *pcf, unsigned int limit)
|
|||
pcf_bl->brightness_limit = limit & 0x3f;
|
||||
backlight_update_status(pcf_bl->bl);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf50633_bl_update_status(struct backlight_device *bl)
|
||||
|
@ -136,8 +136,10 @@ static int pcf50633_bl_probe(struct platform_device *pdev)
|
|||
|
||||
pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDDIM, pdata->ramp_time);
|
||||
|
||||
/* Should be different from bl_props.brightness, so we do not exit
|
||||
* update_status early the first time it's called */
|
||||
/*
|
||||
* Should be different from bl_props.brightness, so we do not exit
|
||||
* update_status early the first time it's called
|
||||
*/
|
||||
pcf_bl->brightness = pcf_bl->bl->props.brightness + 1;
|
||||
|
||||
backlight_update_status(pcf_bl->bl);
|
||||
|
|
|
@ -27,7 +27,7 @@ struct platform_lcd {
|
|||
struct plat_lcd_data *pdata;
|
||||
|
||||
unsigned int power;
|
||||
unsigned int suspended : 1;
|
||||
unsigned int suspended:1;
|
||||
};
|
||||
|
||||
static inline struct platform_lcd *to_our_lcd(struct lcd_device *lcd)
|
||||
|
|
|
@ -757,7 +757,7 @@ static int s6e63m0_probe(struct spi_device *spi)
|
|||
lcd->spi = spi;
|
||||
lcd->dev = &spi->dev;
|
||||
|
||||
lcd->lcd_pd = (struct lcd_platform_data *)spi->dev.platform_data;
|
||||
lcd->lcd_pd = spi->dev.platform_data;
|
||||
if (!lcd->lcd_pd) {
|
||||
dev_err(&spi->dev, "platform data is NULL.\n");
|
||||
return -EFAULT;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* tdo24m - SPI-based drivers for Toppoly TDO24M series LCD panels
|
||||
*
|
||||
* Copyright (C) 2008 Marvell International Ltd.
|
||||
* Eric Miao <eric.miao@marvell.com>
|
||||
* Eric Miao <eric.miao@marvell.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -47,7 +47,7 @@ struct tdo24m {
|
|||
((x1) << 9) | 0x100 | (x2))
|
||||
#define CMD_NULL (-1)
|
||||
|
||||
static uint32_t lcd_panel_reset[] = {
|
||||
static const uint32_t lcd_panel_reset[] = {
|
||||
CMD0(0x1), /* reset */
|
||||
CMD0(0x0), /* nop */
|
||||
CMD0(0x0), /* nop */
|
||||
|
@ -55,7 +55,7 @@ static uint32_t lcd_panel_reset[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_panel_on[] = {
|
||||
static const uint32_t lcd_panel_on[] = {
|
||||
CMD0(0x29), /* Display ON */
|
||||
CMD2(0xB8, 0xFF, 0xF9), /* Output Control */
|
||||
CMD0(0x11), /* Sleep out */
|
||||
|
@ -63,7 +63,7 @@ static uint32_t lcd_panel_on[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_panel_off[] = {
|
||||
static const uint32_t lcd_panel_off[] = {
|
||||
CMD0(0x28), /* Display OFF */
|
||||
CMD2(0xB8, 0x80, 0x02), /* Output Control */
|
||||
CMD0(0x10), /* Sleep in */
|
||||
|
@ -71,7 +71,7 @@ static uint32_t lcd_panel_off[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_vga_pass_through_tdo24m[] = {
|
||||
static const uint32_t lcd_vga_pass_through_tdo24m[] = {
|
||||
CMD1(0xB0, 0x16),
|
||||
CMD1(0xBC, 0x80),
|
||||
CMD1(0xE1, 0x00),
|
||||
|
@ -80,7 +80,7 @@ static uint32_t lcd_vga_pass_through_tdo24m[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_qvga_pass_through_tdo24m[] = {
|
||||
static const uint32_t lcd_qvga_pass_through_tdo24m[] = {
|
||||
CMD1(0xB0, 0x16),
|
||||
CMD1(0xBC, 0x81),
|
||||
CMD1(0xE1, 0x00),
|
||||
|
@ -89,8 +89,8 @@ static uint32_t lcd_qvga_pass_through_tdo24m[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_vga_transfer_tdo24m[] = {
|
||||
CMD1(0xcf, 0x02), /* Blanking period control (1) */
|
||||
static const uint32_t lcd_vga_transfer_tdo24m[] = {
|
||||
CMD1(0xcf, 0x02), /* Blanking period control (1) */
|
||||
CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */
|
||||
CMD1(0xd1, 0x01), /* CKV timing control on/off */
|
||||
CMD2(0xd2, 0x14, 0x00), /* CKV 1,2 timing control */
|
||||
|
@ -102,7 +102,7 @@ static uint32_t lcd_vga_transfer_tdo24m[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_qvga_transfer[] = {
|
||||
static const uint32_t lcd_qvga_transfer[] = {
|
||||
CMD1(0xd6, 0x02), /* Blanking period control (1) */
|
||||
CMD2(0xd7, 0x08, 0x04), /* Blanking period control (2) */
|
||||
CMD1(0xd8, 0x01), /* CKV timing control on/off */
|
||||
|
@ -115,7 +115,7 @@ static uint32_t lcd_qvga_transfer[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_vga_pass_through_tdo35s[] = {
|
||||
static const uint32_t lcd_vga_pass_through_tdo35s[] = {
|
||||
CMD1(0xB0, 0x16),
|
||||
CMD1(0xBC, 0x80),
|
||||
CMD1(0xE1, 0x00),
|
||||
|
@ -123,7 +123,7 @@ static uint32_t lcd_vga_pass_through_tdo35s[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_qvga_pass_through_tdo35s[] = {
|
||||
static const uint32_t lcd_qvga_pass_through_tdo35s[] = {
|
||||
CMD1(0xB0, 0x16),
|
||||
CMD1(0xBC, 0x81),
|
||||
CMD1(0xE1, 0x00),
|
||||
|
@ -131,8 +131,8 @@ static uint32_t lcd_qvga_pass_through_tdo35s[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_vga_transfer_tdo35s[] = {
|
||||
CMD1(0xcf, 0x02), /* Blanking period control (1) */
|
||||
static const uint32_t lcd_vga_transfer_tdo35s[] = {
|
||||
CMD1(0xcf, 0x02), /* Blanking period control (1) */
|
||||
CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */
|
||||
CMD1(0xd1, 0x01), /* CKV timing control on/off */
|
||||
CMD2(0xd2, 0x00, 0x1e), /* CKV 1,2 timing control */
|
||||
|
@ -144,7 +144,7 @@ static uint32_t lcd_vga_transfer_tdo35s[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static uint32_t lcd_panel_config[] = {
|
||||
static const uint32_t lcd_panel_config[] = {
|
||||
CMD2(0xb8, 0xff, 0xf9), /* Output control */
|
||||
CMD0(0x11), /* sleep out */
|
||||
CMD1(0xba, 0x01), /* Display mode (1) */
|
||||
|
@ -175,10 +175,11 @@ static uint32_t lcd_panel_config[] = {
|
|||
CMD_NULL,
|
||||
};
|
||||
|
||||
static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array)
|
||||
static int tdo24m_writes(struct tdo24m *lcd, const uint32_t *array)
|
||||
{
|
||||
struct spi_transfer *x = &lcd->xfer;
|
||||
uint32_t data, *p = array;
|
||||
const uint32_t *p = array;
|
||||
uint32_t data;
|
||||
int nparams, err = 0;
|
||||
|
||||
for (; *p != CMD_NULL; p++) {
|
||||
|
|
|
@ -92,14 +92,12 @@ static int tosa_bl_probe(struct i2c_client *client,
|
|||
|
||||
data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj;
|
||||
|
||||
ret = devm_gpio_request(&client->dev, TOSA_GPIO_BL_C20MA, "backlight");
|
||||
ret = devm_gpio_request_one(&client->dev, TOSA_GPIO_BL_C20MA,
|
||||
GPIOF_OUT_INIT_LOW, "backlight");
|
||||
if (ret) {
|
||||
dev_dbg(&data->bl->dev, "Unable to request gpio!\n");
|
||||
return ret;
|
||||
}
|
||||
ret = gpio_direction_output(TOSA_GPIO_BL_C20MA, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
data->i2c = client;
|
||||
|
@ -163,7 +161,6 @@ static const struct i2c_device_id tosa_bl_id[] = {
|
|||
{ },
|
||||
};
|
||||
|
||||
|
||||
static struct i2c_driver tosa_bl_driver = {
|
||||
.driver = {
|
||||
.name = "tosa-bl",
|
||||
|
|
|
@ -63,7 +63,7 @@ static int tosa_tg_send(struct spi_device *spi, int adrs, uint8_t data)
|
|||
int tosa_bl_enable(struct spi_device *spi, int enable)
|
||||
{
|
||||
/* bl_enable GP04=1 otherwise GP04=0*/
|
||||
return tosa_tg_send(spi, TG_GPODR2, enable? 0x01 : 0x00);
|
||||
return tosa_tg_send(spi, TG_GPODR2, enable ? 0x01 : 0x00);
|
||||
}
|
||||
EXPORT_SYMBOL(tosa_bl_enable);
|
||||
|
||||
|
@ -91,15 +91,17 @@ static void tosa_lcd_tg_on(struct tosa_lcd_data *data)
|
|||
tosa_tg_send(spi, TG_PNLCTL, value);
|
||||
|
||||
/* TG LCD pannel power up */
|
||||
tosa_tg_send(spi, TG_PINICTL,0x4);
|
||||
tosa_tg_send(spi, TG_PINICTL, 0x4);
|
||||
mdelay(50);
|
||||
|
||||
/* TG LCD GVSS */
|
||||
tosa_tg_send(spi, TG_PINICTL,0x0);
|
||||
tosa_tg_send(spi, TG_PINICTL, 0x0);
|
||||
|
||||
if (!data->i2c) {
|
||||
/* after the pannel is powered up the first time, we can access the i2c bus */
|
||||
/* so probe for the DAC */
|
||||
/*
|
||||
* after the pannel is powered up the first time,
|
||||
* we can access the i2c bus so probe for the DAC
|
||||
*/
|
||||
struct i2c_adapter *adap = i2c_get_adapter(0);
|
||||
struct i2c_board_info info = {
|
||||
.type = "tosa-bl",
|
||||
|
@ -115,11 +117,11 @@ static void tosa_lcd_tg_off(struct tosa_lcd_data *data)
|
|||
struct spi_device *spi = data->spi;
|
||||
|
||||
/* TG LCD VHSA off */
|
||||
tosa_tg_send(spi, TG_PINICTL,0x4);
|
||||
tosa_tg_send(spi, TG_PINICTL, 0x4);
|
||||
mdelay(50);
|
||||
|
||||
/* TG LCD signal off */
|
||||
tosa_tg_send(spi, TG_PINICTL,0x6);
|
||||
tosa_tg_send(spi, TG_PINICTL, 0x6);
|
||||
mdelay(50);
|
||||
|
||||
/* TG Off */
|
||||
|
@ -193,17 +195,13 @@ static int tosa_lcd_probe(struct spi_device *spi)
|
|||
data->spi = spi;
|
||||
dev_set_drvdata(&spi->dev, data);
|
||||
|
||||
ret = devm_gpio_request(&spi->dev, TOSA_GPIO_TG_ON, "tg #pwr");
|
||||
ret = devm_gpio_request_one(&spi->dev, TOSA_GPIO_TG_ON,
|
||||
GPIOF_OUT_INIT_LOW, "tg #pwr");
|
||||
if (ret < 0)
|
||||
goto err_gpio_tg;
|
||||
|
||||
mdelay(60);
|
||||
|
||||
ret = gpio_direction_output(TOSA_GPIO_TG_ON, 0);
|
||||
if (ret < 0)
|
||||
goto err_gpio_tg;
|
||||
|
||||
mdelay(60);
|
||||
tosa_lcd_tg_init(data);
|
||||
|
||||
tosa_lcd_tg_on(data);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
/* Device initialisation sequences */
|
||||
|
||||
static struct ili9320_reg vgg_init1[] = {
|
||||
static const struct ili9320_reg vgg_init1[] = {
|
||||
{
|
||||
.address = ILI9320_POWER1,
|
||||
.value = ILI9320_POWER1_AP(0) | ILI9320_POWER1_BT(0),
|
||||
|
@ -43,7 +43,7 @@ static struct ili9320_reg vgg_init1[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct ili9320_reg vgg_init2[] = {
|
||||
static const struct ili9320_reg vgg_init2[] = {
|
||||
{
|
||||
.address = ILI9320_POWER1,
|
||||
.value = (ILI9320_POWER1_AP(3) | ILI9320_POWER1_APE |
|
||||
|
@ -54,7 +54,7 @@ static struct ili9320_reg vgg_init2[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static struct ili9320_reg vgg_gamma[] = {
|
||||
static const struct ili9320_reg vgg_gamma[] = {
|
||||
{
|
||||
.address = ILI9320_GAMMA1,
|
||||
.value = 0x0000,
|
||||
|
@ -89,7 +89,7 @@ static struct ili9320_reg vgg_gamma[] = {
|
|||
|
||||
};
|
||||
|
||||
static struct ili9320_reg vgg_init0[] = {
|
||||
static const struct ili9320_reg vgg_init0[] = {
|
||||
[0] = {
|
||||
/* set direction and scan mode gate */
|
||||
.address = ILI9320_DRIVER,
|
||||
|
@ -217,7 +217,7 @@ static int vgg2432a4_resume(struct spi_device *spi)
|
|||
}
|
||||
#else
|
||||
#define vgg2432a4_suspend NULL
|
||||
#define vgg2432a4_resume NULL
|
||||
#define vgg2432a4_resume NULL
|
||||
#endif
|
||||
|
||||
static struct ili9320_client vgg2432a4_client = {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <linux/poll.h>
|
||||
|
||||
|
||||
static loff_t bad_file_llseek(struct file *file, loff_t offset, int origin)
|
||||
static loff_t bad_file_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
|
|
@ -1601,8 +1601,10 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
|
|||
info->thread = NULL;
|
||||
|
||||
psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
|
||||
if (psinfo == NULL)
|
||||
if (psinfo == NULL) {
|
||||
info->psinfo.data = NULL; /* So we don't free this wrongly */
|
||||
return 0;
|
||||
}
|
||||
|
||||
fill_note(&info->psinfo, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ static int load_em86(struct linux_binprm *bprm)
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
bprm->recursion_depth++; /* Well, the bang-shell is implicit... */
|
||||
allow_write_access(bprm->file);
|
||||
fput(bprm->file);
|
||||
bprm->file = NULL;
|
||||
|
|
|
@ -117,10 +117,6 @@ static int load_misc_binary(struct linux_binprm *bprm)
|
|||
if (!enabled)
|
||||
goto _ret;
|
||||
|
||||
retval = -ENOEXEC;
|
||||
if (bprm->recursion_depth > BINPRM_MAX_RECURSION)
|
||||
goto _ret;
|
||||
|
||||
/* to keep locking time low, we copy the interpreter string */
|
||||
read_lock(&entries_lock);
|
||||
fmt = check_file(bprm);
|
||||
|
@ -197,8 +193,6 @@ static int load_misc_binary(struct linux_binprm *bprm)
|
|||
if (retval < 0)
|
||||
goto _error;
|
||||
|
||||
bprm->recursion_depth++;
|
||||
|
||||
retval = search_binary_handler(bprm);
|
||||
if (retval < 0)
|
||||
goto _error;
|
||||
|
|
|
@ -22,15 +22,13 @@ static int load_script(struct linux_binprm *bprm)
|
|||
char interp[BINPRM_BUF_SIZE];
|
||||
int retval;
|
||||
|
||||
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') ||
|
||||
(bprm->recursion_depth > BINPRM_MAX_RECURSION))
|
||||
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
|
||||
return -ENOEXEC;
|
||||
/*
|
||||
* This section does the #! interpretation.
|
||||
* Sorta complicated, but hopefully it will work. -TYT
|
||||
*/
|
||||
|
||||
bprm->recursion_depth++;
|
||||
allow_write_access(bprm->file);
|
||||
fput(bprm->file);
|
||||
bprm->file = NULL;
|
||||
|
|
|
@ -321,7 +321,7 @@ static int blkdev_write_end(struct file *file, struct address_space *mapping,
|
|||
* for a block special file file->f_path.dentry->d_inode->i_size is zero
|
||||
* so we compute the size by hand (just as in block_read/write above)
|
||||
*/
|
||||
static loff_t block_llseek(struct file *file, loff_t offset, int origin)
|
||||
static loff_t block_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
struct inode *bd_inode = file->f_mapping->host;
|
||||
loff_t size;
|
||||
|
@ -331,7 +331,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
|
|||
size = i_size_read(bd_inode);
|
||||
|
||||
retval = -EINVAL;
|
||||
switch (origin) {
|
||||
switch (whence) {
|
||||
case SEEK_END:
|
||||
offset += size;
|
||||
break;
|
||||
|
|
|
@ -2120,7 +2120,7 @@ static long btrfs_fallocate(struct file *file, int mode,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
|
||||
static int find_desired_extent(struct inode *inode, loff_t *offset, int whence)
|
||||
{
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
struct extent_map *em;
|
||||
|
@ -2154,7 +2154,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
|
|||
* before the position we want in case there is outstanding delalloc
|
||||
* going on here.
|
||||
*/
|
||||
if (origin == SEEK_HOLE && start != 0) {
|
||||
if (whence == SEEK_HOLE && start != 0) {
|
||||
if (start <= root->sectorsize)
|
||||
em = btrfs_get_extent_fiemap(inode, NULL, 0, 0,
|
||||
root->sectorsize, 0);
|
||||
|
@ -2188,13 +2188,13 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
|
|||
}
|
||||
}
|
||||
|
||||
if (origin == SEEK_HOLE) {
|
||||
if (whence == SEEK_HOLE) {
|
||||
*offset = start;
|
||||
free_extent_map(em);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (origin == SEEK_DATA) {
|
||||
if (whence == SEEK_DATA) {
|
||||
if (em->block_start == EXTENT_MAP_DELALLOC) {
|
||||
if (start >= inode->i_size) {
|
||||
free_extent_map(em);
|
||||
|
@ -2231,16 +2231,16 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
|
||||
static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
switch (origin) {
|
||||
switch (whence) {
|
||||
case SEEK_END:
|
||||
case SEEK_CUR:
|
||||
offset = generic_file_llseek(file, offset, origin);
|
||||
offset = generic_file_llseek(file, offset, whence);
|
||||
goto out;
|
||||
case SEEK_DATA:
|
||||
case SEEK_HOLE:
|
||||
|
@ -2249,7 +2249,7 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = find_desired_extent(inode, &offset, origin);
|
||||
ret = find_desired_extent(inode, &offset, whence);
|
||||
if (ret) {
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return ret;
|
||||
|
|
|
@ -454,7 +454,7 @@ static void reset_readdir(struct ceph_file_info *fi)
|
|||
fi->flags &= ~CEPH_F_ATEND;
|
||||
}
|
||||
|
||||
static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int origin)
|
||||
static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
struct ceph_file_info *fi = file->private_data;
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
|
@ -463,7 +463,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int origin)
|
|||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
retval = -EINVAL;
|
||||
switch (origin) {
|
||||
switch (whence) {
|
||||
case SEEK_END:
|
||||
offset += inode->i_size + 2; /* FIXME */
|
||||
break;
|
||||
|
|
|
@ -797,7 +797,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
|||
/*
|
||||
* llseek. be sure to verify file size on SEEK_END.
|
||||
*/
|
||||
static loff_t ceph_llseek(struct file *file, loff_t offset, int origin)
|
||||
static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
int ret;
|
||||
|
@ -805,7 +805,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int origin)
|
|||
mutex_lock(&inode->i_mutex);
|
||||
__ceph_do_pending_vmtruncate(inode);
|
||||
|
||||
if (origin == SEEK_END || origin == SEEK_DATA || origin == SEEK_HOLE) {
|
||||
if (whence == SEEK_END || whence == SEEK_DATA || whence == SEEK_HOLE) {
|
||||
ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE);
|
||||
if (ret < 0) {
|
||||
offset = ret;
|
||||
|
@ -813,7 +813,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int origin)
|
|||
}
|
||||
}
|
||||
|
||||
switch (origin) {
|
||||
switch (whence) {
|
||||
case SEEK_END:
|
||||
offset += inode->i_size;
|
||||
break;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue