提交 848b8141 编写于 作者: L Linus Torvalds

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
  ...
......@@ -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,
};
* 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>;
};
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
~~~~~~~~~~~~~~
......
......@@ -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 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_initcall(__machine_initcall_##mach##_##fn, id);
#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)
{
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;
asmlinkage long compat_sys_sched_rr_get_interval_wrapper(u32 pid,
struct compat_timespec __user *interval)
{
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),
......
/* */
/* */
......@@ -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.
......
/* 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;
}
......
此差异已折叠。
......@@ -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;
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;
cancel_work_sync(&d->work);
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;
skipflags = DEVFL_GDALLOC | DEVFL_NEWSIZE | DEVFL_TKILL;
if (cnt >= 3) {
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, &params.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
......
/*
* 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)
......
/*
* 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 = &reg;
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, &regs[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;
}
/* 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;
goto err_disable_clock;
}
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 */
rtc_device_unregister(config->rtc);
spear_rtc_disable_interrupt(config);
clk_disable_unprepare(config->clk);
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);
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",
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
新手
引导
客服 返回
顶部