Merge branch 'akpm' (incoming from Andrew)

Merge second patch-bomb from Andrew Morton:
 - various misc bits
 - the rest of MM
 - add generic fixmap.h, use it
 - backlight updates
 - dynamic_debug updates
 - printk() updates
 - checkpatch updates
 - binfmt_elf
 - ramfs
 - init/
 - autofs4
 - drivers/rtc
 - nilfs
 - hfsplus
 - Documentation/
 - coredump
 - procfs
 - fork
 - exec
 - kexec
 - kdump
 - partitions
 - rapidio
 - rbtree
 - userns
 - memstick
 - w1
 - decompressors

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (197 commits)
  lib/decompress_unlz4.c: always set an error return code on failures
  romfs: fix returm err while getting inode in fill_super
  drivers/w1/masters/w1-gpio.c: add strong pullup emulation
  drivers/memstick/host/rtsx_pci_ms.c: fix ms card data transfer bug
  userns: relax the posix_acl_valid() checks
  arch/sh/kernel/dwarf.c: use rbtree postorder iteration helper instead of solution using repeated rb_erase()
  fs-ext3-use-rbtree-postorder-iteration-helper-instead-of-opencoding-fix
  fs/ext3: use rbtree postorder iteration helper instead of opencoding
  fs/jffs2: use rbtree postorder iteration helper instead of opencoding
  fs/ext4: use rbtree postorder iteration helper instead of opencoding
  fs/ubifs: use rbtree postorder iteration helper instead of opencoding
  net/netfilter/ipset/ip_set_hash_netiface.c: use rbtree postorder iteration instead of opencoding
  rbtree/test: test rbtree_postorder_for_each_entry_safe()
  rbtree/test: move rb_node to the middle of the test struct
  rapidio: add modular rapidio core build into powerpc and mips branches
  partitions/efi: complete documentation of gpt kernel param purpose
  kdump: add /sys/kernel/vmcoreinfo ABI documentation
  kdump: fix exported size of vmcoreinfo note
  kexec: add sysctl to disable kexec_load
  fs/exec.c: call arch_pick_mmap_layout() only once
  ...
This commit is contained in:
Linus Torvalds 2014-01-23 19:11:50 -08:00
commit 3aacd625f2
231 changed files with 3339 additions and 2187 deletions

View file

@ -0,0 +1,14 @@
What: /sys/kernel/vmcoreinfo
Date: October 2007
KernelVersion: 2.6.24
Contact: Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
Kexec Mailing List <kexec@lists.infradead.org>
Vivek Goyal <vgoyal@redhat.com>
Description
Shows physical address and size of vmcoreinfo ELF note.
First value contains physical address of note in hex and
second value contains the size of note in hex. This ELF
note info is parsed by second kernel and exported to user
space as part of ELF note in /proc/vmcore file. This note
contains various information like struct size, symbol
values, page size etc.

View file

@ -36,21 +36,30 @@ allowing one to squeeze more programs onto an average installation or
rescue floppy disk.
2) Kernel Command Line Parameters
2) Parameters
---------------------------------
2a) Kernel Command Line Parameters
ramdisk_size=N
==============
This parameter tells the RAM disk driver to set up RAM disks of N k size. The
default is 4096 (4 MB) (8192 (8 MB) on S390).
default is 4096 (4 MB).
ramdisk_blocksize=N
===================
2b) Module parameters
This parameter tells the RAM disk driver how many bytes to use per block. The
default is 1024 (BLOCK_SIZE).
rd_nr
=====
/dev/ramX devices created.
max_part
========
Maximum partition number.
rd_size
=======
See ramdisk_size.
3) Using "rdev -r"
------------------

View file

@ -285,7 +285,7 @@ A: This is what you would need in your kernel code to receive notifications.
return NOTIFY_OK;
}
static struct notifier_block foobar_cpu_notifer =
static struct notifier_block foobar_cpu_notifier =
{
.notifier_call = foobar_cpu_callback,
};

View file

@ -0,0 +1,27 @@
Haoyu Microelectronics HYM8563 Real Time Clock
The HYM8563 provides basic rtc and alarm functionality
as well as a clock output of up to 32kHz.
Required properties:
- compatible: should be: "haoyu,hym8563"
- reg: i2c address
- interrupts: rtc alarm/event interrupt
- #clock-cells: the value should be 0
Example:
hym8563: hym8563@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
#clock-cells = <0>;
};
device {
...
clocks = <&hym8563>;
...
};

View file

@ -0,0 +1,12 @@
* Maxim (Dallas) DS1742/DS1743 Real Time Clock
Required properties:
- compatible: Should contain "maxim,ds1742".
- reg: Physical base address of the RTC and length of memory
mapped region.
Example:
rtc: rtc@10000000 {
compatible = "maxim,ds1742";
reg = <0x10000000 0x800>;
};

View file

@ -34,6 +34,7 @@ fsl Freescale Semiconductor
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
gmt Global Mixed-mode Technology, Inc.
haoyu Haoyu Microelectronic Co. Ltd.
hisilicon Hisilicon Limited.
hp Hewlett Packard
ibm International Business Machines (IBM)

View file

@ -108,6 +108,12 @@ If your query set is big, you can batch them too:
~# cat query-batch-file > <debugfs>/dynamic_debug/control
A another way is to use wildcard. The match rule support '*' (matches
zero or more characters) and '?' (matches exactly one character).For
example, you can match all usb drivers:
~# echo "file drivers/usb/* +p" > <debugfs>/dynamic_debug/control
At the syntactical level, a command comprises a sequence of match
specifications, followed by a flags change specification.
@ -315,6 +321,9 @@ nullarbor:~ # echo -n 'func svc_process -p' >
nullarbor:~ # echo -n 'format "nfsd: READ" +p' >
<debugfs>/dynamic_debug/control
// enable messages in files of which the pathes include string "usb"
nullarbor:~ # echo -n '*usb* +p' > <debugfs>/dynamic_debug/control
// enable all messages
nullarbor:~ # echo -n '+p' > <debugfs>/dynamic_debug/control

View file

@ -10,24 +10,32 @@ afs.txt
- info and examples for the distributed AFS (Andrew File System) fs.
affs.txt
- info and mount options for the Amiga Fast File System.
autofs4-mount-control.txt
- info on device control operations for autofs4 module.
automount-support.txt
- information about filesystem automount support.
befs.txt
- information about the BeOS filesystem for Linux.
bfs.txt
- info for the SCO UnixWare Boot Filesystem (BFS).
btrfs.txt
- info for the BTRFS filesystem.
caching/
- directory containing filesystem cache documentation.
ceph.txt
- info for the Ceph Distributed File System
cifs.txt
- description of the CIFS filesystem.
- info for the Ceph Distributed File System.
cifs/
- directory containing CIFS filesystem documentation and example code.
coda.txt
- description of the CODA filesystem.
configfs/
- directory containing configfs documentation and example code.
cramfs.txt
- info on the cram filesystem for small storage (ROMs etc).
dentry-locking.txt
- info on the RCU-based dcache locking model.
debugfs.txt
- info on the debugfs filesystem.
devpts.txt
- info on the devpts filesystem.
directory-locking
- info about the locking scheme used for directory operations.
dlmfs.txt
@ -35,7 +43,7 @@ dlmfs.txt
dnotify.txt
- info about directory notification in Linux.
dnotify_test.c
- example program for dnotify
- example program for dnotify.
ecryptfs.txt
- docs on eCryptfs: stacked cryptographic filesystem for Linux.
efivarfs.txt
@ -48,12 +56,18 @@ ext3.txt
- info, mount options and specifications for the Ext3 filesystem.
ext4.txt
- info, mount options and specifications for the Ext4 filesystem.
files.txt
- info on file management in the Linux kernel.
f2fs.txt
- info and mount options for the F2FS filesystem.
fiemap.txt
- info on fiemap ioctl.
files.txt
- info on file management in the Linux kernel.
fuse.txt
- info on the Filesystem in User SpacE including mount options.
gfs2-glocks.txt
- info on the Global File System 2 - Glock internal locking rules.
gfs2-uevents.txt
- info on the Global File System 2 - uevents.
gfs2.txt
- info on the Global File System 2.
hfs.txt
@ -84,40 +98,58 @@ ntfs.txt
- info and mount options for the NTFS filesystem (Windows NT).
ocfs2.txt
- info and mount options for the OCFS2 clustered filesystem.
omfs.txt
- info on the Optimized MPEG FileSystem.
path-lookup.txt
- info on path walking and name lookup locking.
pohmelfs/
- directory containing pohmelfs filesystem documentation.
porting
- various information on filesystem porting.
proc.txt
- info on Linux's /proc filesystem.
qnx6.txt
- info on the QNX6 filesystem.
quota.txt
- info on Quota subsystem.
ramfs-rootfs-initramfs.txt
- info on the 'in memory' filesystems ramfs, rootfs and initramfs.
reiser4.txt
- info on the Reiser4 filesystem based on dancing tree algorithms.
relay.txt
- info on relay, for efficient streaming from kernel to user space.
romfs.txt
- description of the ROMFS filesystem.
seq_file.txt
- how to use the seq_file API
- how to use the seq_file API.
sharedsubtree.txt
- a description of shared subtrees for namespaces.
spufs.txt
- info and mount options for the SPU filesystem used on Cell.
squashfs.txt
- info on the squashfs filesystem.
sysfs-pci.txt
- info on accessing PCI device resources through sysfs.
sysfs-tagging.txt
- info on sysfs tagging to avoid duplicates.
sysfs.txt
- info on sysfs, a ram-based filesystem for exporting kernel objects.
sysv-fs.txt
- info on the SystemV/V7/Xenix/Coherent filesystem.
tmpfs.txt
- info on tmpfs, a filesystem that holds all files in virtual memory.
ubifs.txt
- info on the Unsorted Block Images FileSystem.
udf.txt
- info and mount options for the UDF filesystem.
ufs.txt
- info on the ufs filesystem.
vfat.txt
- info on using the VFAT filesystem used in Windows NT and Windows 95
- info on using the VFAT filesystem used in Windows NT and Windows 95.
vfs.txt
- overview of the Virtual File System
- overview of the Virtual File System.
xfs-delayed-logging-design.txt
- info on the XFS Delayed Logging Design.
xfs-self-describing-metadata.txt
- info on XFS Self Describing Metadata.
xfs.txt
- info and mount options for the XFS filesystem.
xip.txt

View file

@ -81,6 +81,62 @@ nodiscard(*) The discard/TRIM commands are sent to the underlying
block device when blocks are freed. This is useful
for SSD devices and sparse/thinly-provisioned LUNs.
Ioctls
======
There is some NILFS2 specific functionality which can be accessed by applications
through the system call interfaces. The list of all NILFS2 specific ioctls are
shown in the table below.
Table of NILFS2 specific ioctls
..............................................................................
Ioctl Description
NILFS_IOCTL_CHANGE_CPMODE Change mode of given checkpoint between
checkpoint and snapshot state. This ioctl is
used in chcp and mkcp utilities.
NILFS_IOCTL_DELETE_CHECKPOINT Remove checkpoint from NILFS2 file system.
This ioctl is used in rmcp utility.
NILFS_IOCTL_GET_CPINFO Return info about requested checkpoints. This
ioctl is used in lscp utility and by
nilfs_cleanerd daemon.
NILFS_IOCTL_GET_CPSTAT Return checkpoints statistics. This ioctl is
used by lscp, rmcp utilities and by
nilfs_cleanerd daemon.
NILFS_IOCTL_GET_SUINFO Return segment usage info about requested
segments. This ioctl is used in lssu,
nilfs_resize utilities and by nilfs_cleanerd
daemon.
NILFS_IOCTL_GET_SUSTAT Return segment usage statistics. This ioctl
is used in lssu, nilfs_resize utilities and
by nilfs_cleanerd daemon.
NILFS_IOCTL_GET_VINFO Return information on virtual block addresses.
This ioctl is used by nilfs_cleanerd daemon.
NILFS_IOCTL_GET_BDESCS Return information about descriptors of disk
block numbers. This ioctl is used by
nilfs_cleanerd daemon.
NILFS_IOCTL_CLEAN_SEGMENTS Do garbage collection operation in the
environment of requested parameters from
userspace. This ioctl is used by
nilfs_cleanerd daemon.
NILFS_IOCTL_SYNC Make a checkpoint. This ioctl is used in
mkcp utility.
NILFS_IOCTL_RESIZE Resize NILFS2 volume. This ioctl is used
by nilfs_resize utility.
NILFS_IOCTL_SET_ALLOC_RANGE Define lower limit of segments in bytes and
upper limit of segments in bytes. This ioctl
is used by nilfs_resize utility.
NILFS2 usage
============

View file

@ -108,12 +108,12 @@ static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);
is equivalent to doing:
static struct device_attribute dev_attr_foo = {
.attr = {
.attr = {
.name = "foo",
.mode = S_IWUSR | S_IRUGO,
.show = show_foo,
.store = store_foo,
},
.show = show_foo,
.store = store_foo,
};

View file

@ -1059,7 +1059,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
debugfs files are removed at module unload time.
gpt [EFI] Forces disk with valid GPT signature but
invalid Protective MBR to be treated as GPT.
invalid Protective MBR to be treated as GPT. If the
primary GPT is corrupted, it enables the backup/alternate
GPT to be used instead.
grcan.enable0= [HW] Configuration of physical interface 0. Determines
the "Enable 0" bit of the configuration register.
@ -1461,6 +1463,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Valid arguments: on, off
Default: on
kmemcheck= [X86] Boot-time kmemcheck enable/disable/one-shot mode
Valid arguments: 0, 1, 2
kmemcheck=0 (disabled)
kmemcheck=1 (enabled)
kmemcheck=2 (one-shot mode)
Default: 2 (one-shot mode)
kstack=N [X86] Print N words from the kernel stack
in oops dumps.

View file

@ -55,14 +55,21 @@ Struct Resources:
For printing struct resources. The 'R' and 'r' specifiers result in a
printed resource with ('R') or without ('r') a decoded flags member.
Physical addresses:
Physical addresses types phys_addr_t:
%pa 0x01234567 or 0x0123456789abcdef
%pa[p] 0x01234567 or 0x0123456789abcdef
For printing a phys_addr_t type (and its derivatives, such as
resource_size_t) which can vary based on build options, regardless of
the width of the CPU data path. Passed by reference.
DMA addresses types dma_addr_t:
%pad 0x01234567 or 0x0123456789abcdef
For printing a dma_addr_t type which can vary based on build options,
regardless of the width of the CPU data path. Passed by reference.
Raw buffer as a hex string:
%*ph 00 01 02 ... 3f
%*phC 00:01:02: ... :3f

View file

@ -33,6 +33,7 @@ show up in /proc/sys/kernel:
- domainname
- hostname
- hotplug
- kexec_load_disabled
- kptr_restrict
- kstack_depth_to_print [ X86 only ]
- l2cr [ PPC only ]
@ -287,6 +288,18 @@ Default value is "/sbin/hotplug".
==============================================================
kexec_load_disabled:
A toggle indicating if the kexec_load syscall has been disabled. This
value defaults to 0 (false: kexec_load enabled), but can be set to 1
(true: kexec_load disabled). Once true, kexec can no longer be used, and
the toggle cannot be set back to false. This allows a kexec image to be
loaded before disabling the syscall, allowing a system to set up (and
later use) an image without it being altered. Generally used together
with the "modules_disabled" sysctl.
==============================================================
kptr_restrict:
This toggle indicates whether restrictions are placed on
@ -331,7 +344,7 @@ A toggle value indicating if modules are allowed to be loaded
in an otherwise modular kernel. This toggle defaults to off
(0), but can be set true (1). Once true, modules can be
neither loaded nor unloaded, and the toggle cannot be set back
to false.
to false. Generally used with the "kexec_load_disabled" toggle.
==============================================================

View file

@ -123,7 +123,7 @@ my $regex_writepage;
# Static regex used. Specified like this for readability and for use with /o
# (process_pid) (cpus ) ( time ) (tpoint ) (details)
my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)';
my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])(\s*[dX.][Nnp.][Hhs.][0-9a-fA-F.]*|)\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)';
my $regex_statname = '[-0-9]*\s\((.*)\).*';
my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*';
@ -270,8 +270,8 @@ EVENT_PROCESS:
while ($traceevent = <STDIN>) {
if ($traceevent =~ /$regex_traceevent/o) {
$process_pid = $1;
$timestamp = $3;
$tracepoint = $4;
$timestamp = $4;
$tracepoint = $5;
$process_pid =~ /(.*)-([0-9]*)$/;
my $process = $1;
@ -299,7 +299,7 @@ EVENT_PROCESS:
$perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}++;
$perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN} = $timestamp;
$details = $5;
$details = $6;
if ($details !~ /$regex_direct_begin/o) {
print "WARNING: Failed to parse mm_vmscan_direct_reclaim_begin as expected\n";
print " $details\n";
@ -322,7 +322,7 @@ EVENT_PROCESS:
$perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] = "$order-$latency";
}
} elsif ($tracepoint eq "mm_vmscan_kswapd_wake") {
$details = $5;
$details = $6;
if ($details !~ /$regex_kswapd_wake/o) {
print "WARNING: Failed to parse mm_vmscan_kswapd_wake as expected\n";
print " $details\n";
@ -356,7 +356,7 @@ EVENT_PROCESS:
} elsif ($tracepoint eq "mm_vmscan_wakeup_kswapd") {
$perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}++;
$details = $5;
$details = $6;
if ($details !~ /$regex_wakeup_kswapd/o) {
print "WARNING: Failed to parse mm_vmscan_wakeup_kswapd as expected\n";
print " $details\n";
@ -366,7 +366,7 @@ EVENT_PROCESS:
my $order = $3;
$perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]++;
} elsif ($tracepoint eq "mm_vmscan_lru_isolate") {
$details = $5;
$details = $6;
if ($details !~ /$regex_lru_isolate/o) {
print "WARNING: Failed to parse mm_vmscan_lru_isolate as expected\n";
print " $details\n";
@ -387,7 +387,7 @@ EVENT_PROCESS:
}
$perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty;
} elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") {
$details = $5;
$details = $6;
if ($details !~ /$regex_lru_shrink_inactive/o) {
print "WARNING: Failed to parse mm_vmscan_lru_shrink_inactive as expected\n";
print " $details\n";
@ -397,7 +397,7 @@ EVENT_PROCESS:
my $nr_reclaimed = $4;
$perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED} += $nr_reclaimed;
} elsif ($tracepoint eq "mm_vmscan_writepage") {
$details = $5;
$details = $6;
if ($details !~ /$regex_writepage/o) {
print "WARNING: Failed to parse mm_vmscan_writepage as expected\n";
print " $details\n";

View file

@ -1,130 +0,0 @@
Started Oct 1999 by Kanoj Sarcar <kanojsarcar@yahoo.com>
The intent of this file is to have an uptodate, running commentary
from different people about how locking and synchronization is done
in the Linux vm code.
page_table_lock & mmap_sem
--------------------------------------
Page stealers pick processes out of the process pool and scan for
the best process to steal pages from. To guarantee the existence
of the victim mm, a mm_count inc and a mmdrop are done in swap_out().
Page stealers hold kernel_lock to protect against a bunch of races.
The vma list of the victim mm is also scanned by the stealer,
and the page_table_lock is used to preserve list sanity against the
process adding/deleting to the list. This also guarantees existence
of the vma. Vma existence is not guaranteed once try_to_swap_out()
drops the page_table_lock. To guarantee the existence of the underlying
file structure, a get_file is done before the swapout() method is
invoked. The page passed into swapout() is guaranteed not to be reused
for a different purpose because the page reference count due to being
present in the user's pte is not released till after swapout() returns.
Any code that modifies the vmlist, or the vm_start/vm_end/
vm_flags:VM_LOCKED/vm_next of any vma *in the list* must prevent
kswapd from looking at the chain.
The rules are:
1. To scan the vmlist (look but don't touch) you must hold the
mmap_sem with read bias, i.e. down_read(&mm->mmap_sem)
2. To modify the vmlist you need to hold the mmap_sem with
read&write bias, i.e. down_write(&mm->mmap_sem) *AND*
you need to take the page_table_lock.
3. The swapper takes _just_ the page_table_lock, this is done
because the mmap_sem can be an extremely long lived lock
and the swapper just cannot sleep on that.
4. The exception to this rule is expand_stack, which just
takes the read lock and the page_table_lock, this is ok
because it doesn't really modify fields anybody relies on.
5. You must be able to guarantee that while holding page_table_lock
or page_table_lock of mm A, you will not try to get either lock
for mm B.
The caveats are:
1. find_vma() makes use of, and updates, the mmap_cache pointer hint.
The update of mmap_cache is racy (page stealer can race with other code
that invokes find_vma with mmap_sem held), but that is okay, since it
is a hint. This can be fixed, if desired, by having find_vma grab the
page_table_lock.
Code that add/delete elements from the vmlist chain are
1. callers of insert_vm_struct
2. callers of merge_segments
3. callers of avl_remove
Code that changes vm_start/vm_end/vm_flags:VM_LOCKED of vma's on
the list:
1. expand_stack
2. mprotect
3. mlock
4. mremap
It is advisable that changes to vm_start/vm_end be protected, although
in some cases it is not really needed. Eg, vm_start is modified by
expand_stack(), it is hard to come up with a destructive scenario without
having the vmlist protection in this case.
The page_table_lock nests with the inode i_mmap_mutex and the kmem cache
c_spinlock spinlocks. This is okay, since the kmem code asks for pages after
dropping c_spinlock. The page_table_lock also nests with pagecache_lock and
pagemap_lru_lock spinlocks, and no code asks for memory with these locks
held.
The page_table_lock is grabbed while holding the kernel_lock spinning monitor.
The page_table_lock is a spin lock.
Note: PTL can also be used to guarantee that no new clones using the
mm start up ... this is a loose form of stability on mm_users. For
example, it is used in copy_mm to protect against a racing tlb_gather_mmu
single address space optimization, so that the zap_page_range (from
truncate) does not lose sending ipi's to cloned threads that might
be spawned underneath it and go to user mode to drag in pte's into tlbs.
swap_lock
--------------
The swap devices are chained in priority order from the "swap_list" header.
The "swap_list" is used for the round-robin swaphandle allocation strategy.
The #free swaphandles is maintained in "nr_swap_pages". These two together
are protected by the swap_lock.
The swap_lock also protects all the device reference counts on the
corresponding swaphandles, maintained in the "swap_map" array, and the
"highest_bit" and "lowest_bit" fields.
The swap_lock is a spinlock, and is never acquired from intr level.
To prevent races between swap space deletion or async readahead swapins
deciding whether a swap handle is being used, ie worthy of being read in
from disk, and an unmap -> swap_free making the handle unused, the swap
delete and readahead code grabs a temp reference on the swaphandle to
prevent warning messages from swap_duplicate <- read_swap_cache_async.
Swap cache locking
------------------
Pages are added into the swap cache with kernel_lock held, to make sure
that multiple pages are not being added (and hence lost) by associating
all of them with the same swaphandle.
Pages are guaranteed not to be removed from the scache if the page is
"shared": ie, other processes hold reference on the page or the associated
swap handle. The only code that does not follow this rule is shrink_mmap,
which deletes pages from the swap cache if no process has a reference on
the page (multiple processes might have references on the corresponding
swap handle though). lookup_swap_cache() races with shrink_mmap, when
establishing a reference on a scache page, so, it must check whether the
page it located is still in the swapcache, or shrink_mmap deleted it.
(This race is due to the fact that shrink_mmap looks at the page ref
count with pagecache_lock, but then drops pagecache_lock before deleting
the page from the scache).
do_wp_page and do_swap_page have MP races in them while trying to figure
out whether a page is "shared", by looking at the page_count + swap_count.
To preserve the sum of the counts, the page lock _must_ be acquired before
calling is_page_shared (else processes might switch their swap_count refs
to the page count refs, after the page count ref has been snapshotted).
Swap device deletion code currently breaks all the scache assumptions,
since it grabs neither mmap_sem nor page_table_lock.

View file

@ -93,6 +93,11 @@ Descriptions of section entries:
N: Files and directories with regex patterns.
N: [^a-z]tegra all files whose path contains the word tegra
One pattern per line. Multiple N: lines acceptable.
scripts/get_maintainer.pl has different behavior for files that
match F: pattern and matches of N: patterns. By default,
get_maintainer will not look at git log history when an F: pattern
match occurs. When an N: match occurs, git log history is used
to also notify the people that have git commit signatures.
X: Files and directories that are NOT maintained, same rules as F:
Files exclusions are tested before file matches.
Can be useful for excluding a specific subdirectory, for instance:
@ -3375,7 +3380,6 @@ M: Jingoo Han <jg1.han@samsung.com>
L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/exynos/exynos_dp*
F: include/video/exynos_dp*
EXYNOS MIPI DISPLAY DRIVERS
M: Inki Dae <inki.dae@samsung.com>
@ -3986,6 +3990,12 @@ S: Orphan
F: Documentation/filesystems/hfs.txt
F: fs/hfs/
HFSPLUS FILESYSTEM
L: linux-fsdevel@vger.kernel.org
S: Orphan
F: Documentation/filesystems/hfsplus.txt
F: fs/hfsplus/
HGA FRAMEBUFFER DRIVER
M: Ferenc Bakonyi <fero@drama.obuda.kando.hu>
L: linux-nvidia@lists.surfsouth.com

View file

@ -539,13 +539,13 @@ config SMP
depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
See also the SMP-HOWTO available at

View file

@ -128,8 +128,8 @@ config SMP
default n
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
if SMP

View file

@ -1470,14 +1470,14 @@ config SMP
depends on MMU || ARM_MPU
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all, single
processor machines. On a single processor machine, the kernel will
run faster if you say N here.
you say Y here, the kernel will run on many, but not all,
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
See also <file:Documentation/x86/i386/IO-APIC.txt>,
<file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at

View file

@ -169,7 +169,11 @@ static inline void outsl(unsigned int port, const void *addr,
}
#define inb_p(port) inb(port)
#define inw_p(port) inw(port)
#define inl_p(port) inl(port)
#define outb_p(val, port) outb((val), (port))
#define outw_p(val, port) outw((val), (port))
#define outl_p(val, port) outl((val), (port))
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem

View file

@ -26,45 +26,7 @@
*/
#include <asm/mem-layout.h>
/*
* Full fixmap support involves set_fixmap() functions, but
* these may not be needed if all we're after is an area for
* highmem kernel mappings.
*/
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
extern void __this_fixmap_does_not_exist(void);
/**
* fix_to_virt -- "index to address" translation.
*
* If anyone tries to use the idx directly without translation,
* we catch the bug with a NULL-deference kernel oops. Illegal
* ranges of incoming indices are caught too.
*/
static inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* This branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
#include <asm-generic/fixmap.h>
#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), \

View file

@ -104,6 +104,7 @@ config HAVE_SETUP_PER_CPU_AREA
config DMI
bool
default y
select DMI_SCAN_MACHINE_NON_EFI_FALLBACK
config EFI
bool

View file

@ -5,8 +5,10 @@
#include <asm/io.h>
/* Use normal IO mappings for DMI */
#define dmi_ioremap ioremap
#define dmi_iounmap(x,l) iounmap(x)
#define dmi_alloc(l) kzalloc(l, GFP_ATOMIC)
#define dmi_early_remap ioremap
#define dmi_early_unmap(x, l) iounmap(x)
#define dmi_remap ioremap
#define dmi_unmap iounmap
#define dmi_alloc(l) kzalloc(l, GFP_ATOMIC)
#endif

View file

@ -71,6 +71,7 @@
#include <linux/compiler.h>
#include <linux/threads.h>
#include <linux/types.h>
#include <linux/bitops.h>
#include <asm/fpu.h>
#include <asm/page.h>

View file

@ -277,13 +277,13 @@ config SMP
bool "Symmetric multi-processing support"
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
People using multiprocessor machines who say Y here should also say

View file

@ -51,37 +51,7 @@ enum fixed_addresses {
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
extern void __this_fixmap_does_not_exist(void);
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without tranlation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
#include <asm-generic/fixmap.h>
#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel( \

View file

@ -30,6 +30,7 @@ config MICROBLAZE
select MODULES_USE_ELF_RELA
select CLONE_BACKWARDS3
select CLKSRC_OF
select BUILDTIME_EXTABLE_SORT
config SWAP
def_bool n

View file

@ -58,52 +58,12 @@ enum fixed_addresses {
extern void __set_fixmap(enum fixed_addresses idx,
phys_addr_t phys, pgprot_t flags);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
/*
* Some hardware wants to get fixmapped without caching.
*/
#define set_fixmap_nocache(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL_CI)
#define clear_fixmap(idx) \
__set_fixmap(idx, 0, __pgprot(0))
#define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_CI
extern void __this_fixmap_does_not_exist(void);
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without tranlation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static __always_inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
#include <asm-generic/fixmap.h>
#endif /* !__ASSEMBLY__ */
#endif

View file

@ -2129,13 +2129,13 @@ config SMP
depends on SYS_SUPPORTS_SMP
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
People using multiprocessor machines who say Y here should also say
@ -2430,7 +2430,7 @@ source "drivers/pcmcia/Kconfig"
source "drivers/pci/hotplug/Kconfig"
config RAPIDIO
bool "RapidIO support"
tristate "RapidIO support"
depends on PCI
default n
help

View file

@ -71,38 +71,7 @@ enum fixed_addresses {
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
extern void __this_fixmap_does_not_exist(void);
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without tranlation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
#include <asm-generic/fixmap.h>
#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))

View file

@ -184,13 +184,13 @@ config SMP
depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
See also <file:Documentation/x86/i386/IO-APIC.txt>,

View file

@ -229,13 +229,13 @@ config SMP
bool "Symmetric multi-processing support"
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
See also <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO

View file

@ -794,7 +794,7 @@ config HAS_RAPIDIO
default n
config RAPIDIO
bool "RapidIO support"
tristate "RapidIO support"
depends on HAS_RAPIDIO || PCI
help
If you say Y here, the kernel will include drivers and
@ -802,7 +802,7 @@ config RAPIDIO
config FSL_RIO
bool "Freescale Embedded SRIO Controller support"
depends on RAPIDIO && HAS_RAPIDIO
depends on RAPIDIO = y && HAS_RAPIDIO
default "n"
---help---
Include support for RapidIO controller on Freescale embedded

View file

@ -58,52 +58,12 @@ enum fixed_addresses {
extern void __set_fixmap (enum fixed_addresses idx,
phys_addr_t phys, pgprot_t flags);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
/*
* Some hardware wants to get fixmapped without caching.
*/
#define set_fixmap_nocache(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL_NCG)
#define clear_fixmap(idx) \
__set_fixmap(idx, 0, __pgprot(0))
#define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_NCG
extern void __this_fixmap_does_not_exist(void);
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without tranlation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static __always_inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
#include <asm-generic/fixmap.h>
#endif /* !__ASSEMBLY__ */
#endif

View file

@ -334,10 +334,10 @@ config SMP
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
See also the SMP-HOWTO available at

View file

@ -701,13 +701,13 @@ config SMP
depends on SYS_SUPPORTS_SMP
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
People using multiprocessor machines who say Y here should also say

View file

@ -79,13 +79,6 @@ extern void __set_fixmap(enum fixed_addresses idx,
unsigned long phys, pgprot_t flags);
extern void __clear_fixmap(enum fixed_addresses idx, pgprot_t flags);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
/*
* Some hardware wants to get fixmapped without caching.
*/
#define set_fixmap_nocache(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
/*
* used by vmalloc.c.
*
@ -101,36 +94,8 @@ extern void __clear_fixmap(enum fixed_addresses idx, pgprot_t flags);
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_NOCACHE
extern void __this_fixmap_does_not_exist(void);
#include <asm-generic/fixmap.h>
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without tranlation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
#endif

View file

@ -995,29 +995,19 @@ static struct unwinder dwarf_unwinder = {
static void dwarf_unwinder_cleanup(void)
{
struct rb_node **fde_rb_node = &fde_root.rb_node;
struct rb_node **cie_rb_node = &cie_root.rb_node;
struct dwarf_fde *fde, *next_fde;
struct dwarf_cie *cie, *next_cie;
/*
* Deallocate all the memory allocated for the DWARF unwinder.
* Traverse all the FDE/CIE lists and remove and free all the
* memory associated with those data structures.
*/
while (*fde_rb_node) {
struct dwarf_fde *fde;
fde = rb_entry(*fde_rb_node, struct dwarf_fde, node);
rb_erase(*fde_rb_node, &fde_root);
rbtree_postorder_for_each_entry_safe(fde, next_fde, &fde_root, node)
kfree(fde);
}
while (*cie_rb_node) {
struct dwarf_cie *cie;
cie = rb_entry(*cie_rb_node, struct dwarf_cie, node);
rb_erase(*cie_rb_node, &cie_root);
rbtree_postorder_for_each_entry_safe(cie, next_cie, &cie_root, node)
kfree(cie);
}
kmem_cache_destroy(dwarf_reg_cachep);
kmem_cache_destroy(dwarf_frame_cachep);

View file

@ -152,10 +152,10 @@ config SMP
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
People using multiprocessor machines who say Y here should also say

View file

@ -25,9 +25,6 @@
#include <asm/kmap_types.h>
#endif
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
/*
* Here we define all the compile-time 'special' virtual
* addresses. The point is to have a constant address at
@ -83,35 +80,7 @@ enum fixed_addresses {
#define FIXADDR_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_SIZE)
#define FIXADDR_BOOT_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_BOOT_SIZE)
extern void __this_fixmap_does_not_exist(void);
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without tranlation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static __always_inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
#include <asm-generic/fixmap.h>
#endif /* !__ASSEMBLY__ */

View file

@ -43,13 +43,6 @@ enum fixed_addresses {
extern void __set_fixmap (enum fixed_addresses idx,
unsigned long phys, pgprot_t flags);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
/*
* Some hardware wants to get fixmapped without caching.
*/
#define set_fixmap_nocache(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
/*
* used by vmalloc.c.
*
@ -62,37 +55,6 @@ extern void __set_fixmap (enum fixed_addresses idx,
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
extern void __this_fixmap_does_not_exist(void);
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without tranlation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
#include <asm-generic/fixmap.h>
#endif

View file

@ -279,13 +279,13 @@ config SMP
bool "Symmetric multi-processing support"
---help---
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
you have a system with more than one CPU, say Y.
a system with only one CPU, say N. If you have a system with more
than one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
If you say N here, the kernel will run on uni- and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
you say Y here, the kernel will run on many, but not all,
singleprocessor machines. On a singleprocessor machine, the kernel
uniprocessor machines. On a uniprocessor machine, the kernel
will run faster if you say N here.
Note that if you say Y here and choose architecture "586" or
@ -731,6 +731,7 @@ config APB_TIMER
# The code disables itself when not needed.
config DMI
default y
select DMI_SCAN_MACHINE_NON_EFI_FALLBACK
bool "Enable DMI scanning" if EXPERT
---help---
Enabled scanning of DMI to identify machine quirks. Say Y

View file

@ -13,7 +13,9 @@ static __always_inline __init void *dmi_alloc(unsigned len)
}
/* Use early IO mappings for DMI because it's initialized early */
#define dmi_ioremap early_ioremap
#define dmi_iounmap early_iounmap
#define dmi_early_remap early_ioremap
#define dmi_early_unmap early_iounmap
#define dmi_remap ioremap
#define dmi_unmap iounmap
#endif /* _ASM_X86_DMI_H */

View file

@ -175,64 +175,7 @@ static inline void __set_fixmap(enum fixed_addresses idx,
}
#endif
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
/*
* Some hardware wants to get fixmapped without caching.
*/
#define set_fixmap_nocache(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
#define clear_fixmap(idx) \
__set_fixmap(idx, 0, __pgprot(0))
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
extern void __this_fixmap_does_not_exist(void);
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without translation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static __always_inline unsigned long fix_to_virt(const unsigned int idx)
{
/*
* this branch gets completely eliminated after inlining,
* except when someone tries to use fixaddr indices in an
* illegal way. (such as mixing up address types or using
* out-of-range indices).
*
* If it doesn't get removed, the linker will complain
* loudly with a reasonably clear error message..
*/
if (idx >= __end_of_fixed_addresses)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
static inline unsigned long virt_to_fix(const unsigned long vaddr)
{
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
return __virt_to_fix(vaddr);
}
/* Return an pointer with offset calculated */
static __always_inline unsigned long
__set_fixmap_offset(enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
{
__set_fixmap(idx, phys, flags);
return fix_to_virt(idx) + (phys & (PAGE_SIZE - 1));
}
#define set_fixmap_offset(idx, phys) \
__set_fixmap_offset(idx, phys, PAGE_KERNEL)
#define set_fixmap_offset_nocache(idx, phys) \
__set_fixmap_offset(idx, phys, PAGE_KERNEL_NOCACHE)
#include <asm-generic/fixmap.h>
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_X86_FIXMAP_H */

View file

@ -108,8 +108,8 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
static inline void get_head_page_multiple(struct page *page, int nr)
{
VM_BUG_ON(page != compound_head(page));
VM_BUG_ON(page_count(page) == 0);
VM_BUG_ON_PAGE(page != compound_head(page), page);
VM_BUG_ON_PAGE(page_count(page) == 0, page);
atomic_add(nr, &page->_count);
SetPageReferenced(page);
}
@ -135,7 +135,7 @@ static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr,
head = pte_page(pte);
page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
do {
VM_BUG_ON(compound_head(page) != head);
VM_BUG_ON_PAGE(compound_head(page) != head, page);
pages[*nr] = page;
if (PageTail(page))
get_huge_page_tail(page);
@ -212,7 +212,7 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr,
head = pte_page(pte);
page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
do {
VM_BUG_ON(compound_head(page) != head);
VM_BUG_ON_PAGE(compound_head(page) != head, page);
pages[*nr] = page;
if (PageTail(page))
get_huge_page_tail(page);

View file

@ -368,7 +368,8 @@ config BLK_DEV_RAM
For details, read <file:Documentation/blockdev/ramdisk.txt>.
To compile this driver as a module, choose M here: the
module will be called rd.
module will be called brd. An alias "rd" has been defined
for historical reasons.
Most normal users won't need the RAM disk functionality, and can
thus say N here.

View file

@ -108,6 +108,9 @@ config DMI_SYSFS
under /sys/firmware/dmi when this option is enabled and
loaded.
config DMI_SCAN_MACHINE_NON_EFI_FALLBACK
bool
config ISCSI_IBFT_FIND
bool "iSCSI Boot Firmware Table Attributes"
depends on X86

View file

@ -116,7 +116,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
{
u8 *buf;
buf = dmi_ioremap(dmi_base, dmi_len);
buf = dmi_early_remap(dmi_base, dmi_len);
if (buf == NULL)
return -1;
@ -124,7 +124,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
add_device_randomness(buf, dmi_len);
dmi_iounmap(buf, dmi_len);
dmi_early_unmap(buf, dmi_len);
return 0;
}
@ -527,18 +527,18 @@ void __init dmi_scan_machine(void)
* needed during early boot. This also means we can
* iounmap the space when we're done with it.
*/
p = dmi_ioremap(efi.smbios, 32);
p = dmi_early_remap(efi.smbios, 32);
if (p == NULL)
goto error;
memcpy_fromio(buf, p, 32);
dmi_iounmap(p, 32);
dmi_early_unmap(p, 32);
if (!dmi_present(buf)) {
dmi_available = 1;
goto out;
}
} else {
p = dmi_ioremap(0xF0000, 0x10000);
} else if (IS_ENABLED(CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK)) {
p = dmi_early_remap(0xF0000, 0x10000);
if (p == NULL)
goto error;
@ -554,12 +554,12 @@ void __init dmi_scan_machine(void)
memcpy_fromio(buf + 16, q, 16);
if (!dmi_present(buf)) {
dmi_available = 1;
dmi_iounmap(p, 0x10000);
dmi_early_unmap(p, 0x10000);
goto out;
}
memcpy(buf, buf + 16, 16);
}
dmi_iounmap(p, 0x10000);
dmi_early_unmap(p, 0x10000);
}
error:
pr_info("DMI not present or invalid.\n");
@ -831,13 +831,13 @@ int dmi_walk(void (*decode)(const struct dmi_header *, void *),
if (!dmi_available)
return -1;
buf = ioremap(dmi_base, dmi_len);
buf = dmi_remap(dmi_base, dmi_len);
if (buf == NULL)
return -1;
dmi_table(buf, dmi_len, dmi_num, decode, private_data);
iounmap(buf);
dmi_unmap(buf);
return 0;
}
EXPORT_SYMBOL_GPL(dmi_walk);

View file

@ -26,13 +26,13 @@
#include "intel_bios.h"
#include "power.h"
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
static void do_gma_backlight_set(struct drm_device *dev)
{
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
struct drm_psb_private *dev_priv = dev->dev_private;
backlight_update_status(dev_priv->backlight_device);
#endif
}
#endif
void gma_backlight_enable(struct drm_device *dev)
{

View file

@ -52,7 +52,7 @@ struct omap_mbox_queue {
struct omap_mbox {
const char *name;
unsigned int irq;
int irq;
struct omap_mbox_queue *txq, *rxq;
struct omap_mbox_ops *ops;
struct device *dev;

View file

@ -145,6 +145,8 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
unsigned int length = sg->length;
u16 sec_cnt = (u16)(length / 512);
u8 val, trans_mode, dma_dir;
struct memstick_dev *card = host->msh->card;
bool pro_card = card->id.type == MEMSTICK_TYPE_PRO;
dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n",
__func__, tpc, (data_dir == READ) ? "READ" : "WRITE",
@ -152,19 +154,21 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
if (data_dir == READ) {
dma_dir = DMA_DIR_FROM_CARD;
trans_mode = MS_TM_AUTO_READ;
trans_mode = pro_card ? MS_TM_AUTO_READ : MS_TM_NORMAL_READ;
} else {
dma_dir = DMA_DIR_TO_CARD;
trans_mode = MS_TM_AUTO_WRITE;
trans_mode = pro_card ? MS_TM_AUTO_WRITE : MS_TM_NORMAL_WRITE;
}
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
0xFF, (u8)(sec_cnt >> 8));
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L,
0xFF, (u8)sec_cnt);
if (pro_card) {
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
0xFF, (u8)(sec_cnt >> 8));
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L,
0xFF, (u8)sec_cnt);
}
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
@ -192,8 +196,14 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
}
rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT))
return -EIO;
if (pro_card) {
if (val & (MS_INT_CMDNK | MS_INT_ERR |
MS_CRC16_ERR | MS_RDY_TIMEOUT))
return -EIO;
} else {
if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT))
return -EIO;
}
return 0;
}
@ -462,8 +472,8 @@ static int rtsx_pci_ms_set_param(struct memstick_host *msh,
clock = 19000000;
ssc_depth = RTSX_SSC_DEPTH_500K;
err = rtsx_pci_write_register(pcr, MS_CFG,
0x18, MS_BUS_WIDTH_1);
err = rtsx_pci_write_register(pcr, MS_CFG, 0x58,
MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT);
if (err < 0)
return err;
} else if (value == MEMSTICK_PAR4) {

View file

@ -175,7 +175,7 @@ static inline int max8998_i2c_get_driver_data(struct i2c_client *i2c,
if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) {
const struct of_device_id *match;
match = of_match_node(max8998_dt_match, i2c->dev.of_node);
return (int)match->data;
return (int)(long)match->data;
}
return (int)id->driver_data;

View file

@ -170,7 +170,7 @@ static int tps65217_probe(struct i2c_client *client,
"Failed to find matching dt id\n");
return -EINVAL;
}
chip_id = (unsigned int)match->data;
chip_id = (unsigned int)(unsigned long)match->data;
status_off = of_property_read_bool(client->dev.of_node,
"ti,pmic-shutdown-controller");
}

View file

@ -212,6 +212,17 @@ config RTC_DRV_DS3232
This driver can also be built as a module. If so, the module
will be called rtc-ds3232.
config RTC_DRV_HYM8563
tristate "Haoyu Microelectronics HYM8563"
depends on I2C && OF
help
Say Y to enable support for the HYM8563 I2C RTC chip. Apart
from the usual rtc functions it provides a clock output of
up to 32kHz.
This driver can also be built as a module. If so, the module
will be called rtc-hym8563.
config RTC_DRV_LP8788
tristate "TI LP8788 RTC driver"
depends on MFD_LP8788
@ -637,7 +648,7 @@ comment "Platform RTC drivers"
config RTC_DRV_CMOS
tristate "PC-style 'CMOS'"
depends on X86 || ARM || M32R || ATARI || PPC || MIPS || SPARC64
depends on X86 || ARM || M32R || PPC || MIPS || SPARC64
default y if X86
help
Say "yes" here to get direct support for the real time clock

View file

@ -55,6 +55,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o
obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o

View file

@ -14,6 +14,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/of.h>
#include <linux/rtc.h>
#include <linux/kdev_t.h>
#include <linux/idr.h>
@ -157,12 +158,27 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
{
struct rtc_device *rtc;
struct rtc_wkalrm alrm;
int id, err;
int of_id = -1, id = -1, err;
if (dev->of_node)
of_id = of_alias_get_id(dev->of_node, "rtc");
else if (dev->parent && dev->parent->of_node)
of_id = of_alias_get_id(dev->parent->of_node, "rtc");
if (of_id >= 0) {
id = ida_simple_get(&rtc_ida, of_id, of_id + 1,
GFP_KERNEL);
if (id < 0)
dev_warn(dev, "/aliases ID %d not available\n",
of_id);
}
id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
err = id;
goto exit;
id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
err = id;
goto exit;
}
}
rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);

View file

@ -198,7 +198,7 @@ static int as3722_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
as3722_rtc->rtc = rtc_device_register("as3722", &pdev->dev,
as3722_rtc->rtc = devm_rtc_device_register(&pdev->dev, "as3722-rtc",
&as3722_rtc_ops, THIS_MODULE);
if (IS_ERR(as3722_rtc->rtc)) {
ret = PTR_ERR(as3722_rtc->rtc);
@ -209,28 +209,16 @@ static int as3722_rtc_probe(struct platform_device *pdev)
as3722_rtc->alarm_irq = platform_get_irq(pdev, 0);
dev_info(&pdev->dev, "RTC interrupt %d\n", as3722_rtc->alarm_irq);
ret = request_threaded_irq(as3722_rtc->alarm_irq, NULL,
ret = devm_request_threaded_irq(&pdev->dev, as3722_rtc->alarm_irq, NULL,
as3722_alarm_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME,
"rtc-alarm", as3722_rtc);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
as3722_rtc->alarm_irq, ret);
goto scrub;
return ret;
}
disable_irq(as3722_rtc->alarm_irq);
return 0;
scrub:
rtc_device_unregister(as3722_rtc->rtc);
return ret;
}
static int as3722_rtc_remove(struct platform_device *pdev)
{
struct as3722_rtc *as3722_rtc = platform_get_drvdata(pdev);
free_irq(as3722_rtc->alarm_irq, as3722_rtc);
rtc_device_unregister(as3722_rtc->rtc);
return 0;
}
#ifdef CONFIG_PM_SLEEP
@ -260,7 +248,6 @@ static const struct dev_pm_ops as3722_rtc_pm_ops = {
static struct platform_driver as3722_rtc_driver = {
.probe = as3722_rtc_probe,
.remove = as3722_rtc_remove,
.driver = {
.name = "as3722-rtc",
.pm = &as3722_rtc_pm_ops,

View file

@ -756,11 +756,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
irq_handler_t rtc_cmos_int_handler;
if (is_hpet_enabled()) {
int err;
rtc_cmos_int_handler = hpet_rtc_interrupt;
err = hpet_register_irq_handler(cmos_interrupt);
if (err != 0) {
retval = hpet_register_irq_handler(cmos_interrupt);
if (retval) {
dev_warn(dev, "hpet_register_irq_handler "
" failed in rtc_init().");
goto cleanup1;
@ -1175,7 +1173,7 @@ static struct platform_driver cmos_platform_driver = {
.remove = __exit_p(cmos_platform_remove),
.shutdown = cmos_platform_shutdown,
.driver = {
.name = (char *) driver_name,
.name = driver_name,
#ifdef CONFIG_PM
.pm = &cmos_pm_ops,
#endif

View file

@ -787,7 +787,6 @@ static int ds1305_remove(struct spi_device *spi)
cancel_work_sync(&ds1305->work);
}
spi_set_drvdata(spi, NULL);
return 0;
}

View file

@ -13,12 +13,13 @@
*/
#include <linux/bcd.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/rtc.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/module.h>
@ -215,12 +216,19 @@ static int ds1742_rtc_remove(struct platform_device *pdev)
return 0;
}
static struct of_device_id __maybe_unused ds1742_rtc_of_match[] = {
{ .compatible = "maxim,ds1742", },
{ }
};
MODULE_DEVICE_TABLE(of, ds1742_rtc_of_match);
static struct platform_driver ds1742_rtc_driver = {
.probe = ds1742_rtc_probe,
.remove = ds1742_rtc_remove,
.driver = {
.name = "rtc-ds1742",
.owner = THIS_MODULE,
.of_match_table = ds1742_rtc_of_match,
},
};

606
drivers/rtc/rtc-hym8563.c Normal file
View file

@ -0,0 +1,606 @@
/*
* Haoyu HYM8563 RTC driver
*
* Copyright (C) 2013 MundoReader S.L.
* Author: Heiko Stuebner <heiko@sntech.de>
*
* based on rtc-HYM8563
* Copyright (C) 2010 ROCKCHIP, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/clk-provider.h>
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
#define HYM8563_CTL1 0x00
#define HYM8563_CTL1_TEST BIT(7)
#define HYM8563_CTL1_STOP BIT(5)
#define HYM8563_CTL1_TESTC BIT(3)
#define HYM8563_CTL2 0x01
#define HYM8563_CTL2_TI_TP BIT(4)
#define HYM8563_CTL2_AF BIT(3)
#define HYM8563_CTL2_TF BIT(2)
#define HYM8563_CTL2_AIE BIT(1)
#define HYM8563_CTL2_TIE BIT(0)
#define HYM8563_SEC 0x02
#define HYM8563_SEC_VL BIT(7)
#define HYM8563_SEC_MASK 0x7f
#define HYM8563_MIN 0x03
#define HYM8563_MIN_MASK 0x7f
#define HYM8563_HOUR 0x04
#define HYM8563_HOUR_MASK 0x3f
#define HYM8563_DAY 0x05
#define HYM8563_DAY_MASK 0x3f
#define HYM8563_WEEKDAY 0x06
#define HYM8563_WEEKDAY_MASK 0x07
#define HYM8563_MONTH 0x07
#define HYM8563_MONTH_CENTURY BIT(7)
#define HYM8563_MONTH_MASK 0x1f
#define HYM8563_YEAR 0x08
#define HYM8563_ALM_MIN 0x09
#define HYM8563_ALM_HOUR 0x0a
#define HYM8563_ALM_DAY 0x0b
#define HYM8563_ALM_WEEK 0x0c
/* Each alarm check can be disabled by setting this bit in the register */
#define HYM8563_ALM_BIT_DISABLE BIT(7)
#define HYM8563_CLKOUT 0x0d
#define HYM8563_CLKOUT_DISABLE BIT(7)
#define HYM8563_CLKOUT_32768 0
#define HYM8563_CLKOUT_1024 1
#define HYM8563_CLKOUT_32 2
#define HYM8563_CLKOUT_1 3
#define HYM8563_CLKOUT_MASK 3
#define HYM8563_TMR_CTL 0x0e
#define HYM8563_TMR_CTL_ENABLE BIT(7)
#define HYM8563_TMR_CTL_4096 0
#define HYM8563_TMR_CTL_64 1
#define HYM8563_TMR_CTL_1 2
#define HYM8563_TMR_CTL_1_60 3
#define HYM8563_TMR_CTL_MASK 3
#define HYM8563_TMR_CNT 0x0f
struct hym8563 {
struct i2c_client *client;
struct rtc_device *rtc;
bool valid;
#ifdef CONFIG_COMMON_CLK
struct clk_hw clkout_hw;
#endif
};
/*
* RTC handling
*/
static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
struct hym8563 *hym8563 = i2c_get_clientdata(client);
u8 buf[7];
int ret;
if (!hym8563->valid) {
dev_warn(&client->dev, "no valid clock/calendar values available\n");
return -EPERM;
}
ret = i2c_smbus_read_i2c_block_data(client, HYM8563_SEC, 7, buf);
tm->tm_sec = bcd2bin(buf[0] & HYM8563_SEC_MASK);
tm->tm_min = bcd2bin(buf[1] & HYM8563_MIN_MASK);
tm->tm_hour = bcd2bin(buf[2] & HYM8563_HOUR_MASK);
tm->tm_mday = bcd2bin(buf[3] & HYM8563_DAY_MASK);
tm->tm_wday = bcd2bin(buf[4] & HYM8563_WEEKDAY_MASK); /* 0 = Sun */
tm->tm_mon = bcd2bin(buf[5] & HYM8563_MONTH_MASK) - 1; /* 0 = Jan */
tm->tm_year = bcd2bin(buf[6]) + 100;
return 0;
}
static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
struct hym8563 *hym8563 = i2c_get_clientdata(client);
u8 buf[7];
int ret;
/* Years >= 2100 are to far in the future, 19XX is to early */
if (tm->tm_year < 100 || tm->tm_year >= 200)
return -EINVAL;
buf[0] = bin2bcd(tm->tm_sec);
buf[1] = bin2bcd(tm->tm_min);
buf[2] = bin2bcd(tm->tm_hour);
buf[3] = bin2bcd(tm->tm_mday);
buf[4] = bin2bcd(tm->tm_wday);
buf[5] = bin2bcd(tm->tm_mon + 1);
/*
* While the HYM8563 has a century flag in the month register,
* it does not seem to carry it over a subsequent write/read.
* So we'll limit ourself to 100 years, starting at 2000 for now.
*/
buf[6] = tm->tm_year - 100;
/*
* CTL1 only contains TEST-mode bits apart from stop,
* so no need to read the value first
*/
ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1,
HYM8563_CTL1_STOP);
if (ret < 0)
return ret;
ret = i2c_smbus_write_i2c_block_data(client, HYM8563_SEC, 7, buf);
if (ret < 0)
return ret;
ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1, 0);
if (ret < 0)
return ret;
hym8563->valid = true;
return 0;
}
static int hym8563_rtc_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
int data;
data = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
if (data < 0)
return data;
if (enabled)
data |= HYM8563_CTL2_AIE;
else
data &= ~HYM8563_CTL2_AIE;
return i2c_smbus_write_byte_data(client, HYM8563_CTL2, data);
};
static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
struct i2c_client *client = to_i2c_client(dev);
struct rtc_time *alm_tm = &alm->time;
u8 buf[4];
int ret;
ret = i2c_smbus_read_i2c_block_data(client, HYM8563_ALM_MIN, 4, buf);
if (ret < 0)
return ret;
/* The alarm only has a minute accuracy */
alm_tm->tm_sec = -1;
alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ?
-1 :
bcd2bin(buf[0] & HYM8563_MIN_MASK);
alm_tm->tm_hour = (buf[1] & HYM8563_ALM_BIT_DISABLE) ?
-1 :
bcd2bin(buf[1] & HYM8563_HOUR_MASK);
alm_tm->tm_mday = (buf[2] & HYM8563_ALM_BIT_DISABLE) ?
-1 :
bcd2bin(buf[2] & HYM8563_DAY_MASK);
alm_tm->tm_wday = (buf[3] & HYM8563_ALM_BIT_DISABLE) ?
-1 :
bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK);
alm_tm->tm_mon = -1;
alm_tm->tm_year = -1;
ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
if (ret < 0)
return ret;
if (ret & HYM8563_CTL2_AIE)
alm->enabled = 1;
return 0;
}
static int hym8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
struct i2c_client *client = to_i2c_client(dev);
struct rtc_time *alm_tm = &alm->time;
u8 buf[4];
int ret;
/*
* The alarm has no seconds so deal with it
*/
if (alm_tm->tm_sec) {
alm_tm->tm_sec = 0;
alm_tm->tm_min++;
if (alm_tm->tm_min >= 60) {
alm_tm->tm_min = 0;
alm_tm->tm_hour++;
if (alm_tm->tm_hour >= 24) {
alm_tm->tm_hour = 0;
alm_tm->tm_mday++;
if (alm_tm->tm_mday > 31)
alm_tm->tm_mday = 0;
}
}
}
ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
if (ret < 0)
return ret;
ret &= ~HYM8563_CTL2_AIE;
ret = i2c_smbus_write_byte_data(client, HYM8563_CTL2, ret);
if (ret < 0)
return ret;
buf[0] = (alm_tm->tm_min < 60 && alm_tm->tm_min >= 0) ?
bin2bcd(alm_tm->tm_min) : HYM8563_ALM_BIT_DISABLE;
buf[1] = (alm_tm->tm_hour < 24 && alm_tm->tm_hour >= 0) ?
bin2bcd(alm_tm->tm_hour) : HYM8563_ALM_BIT_DISABLE;
buf[2] = (alm_tm->tm_mday <= 31 && alm_tm->tm_mday >= 1) ?
bin2bcd(alm_tm->tm_mday) : HYM8563_ALM_BIT_DISABLE;
buf[3] = (alm_tm->tm_wday < 7 && alm_tm->tm_wday >= 0) ?
bin2bcd(alm_tm->tm_wday) : HYM8563_ALM_BIT_DISABLE;
ret = i2c_smbus_write_i2c_block_data(client, HYM8563_ALM_MIN, 4, buf);
if (ret < 0)
return ret;
return hym8563_rtc_alarm_irq_enable(dev, alm->enabled);
}
static const struct rtc_class_ops hym8563_rtc_ops = {
.read_time = hym8563_rtc_read_time,
.set_time = hym8563_rtc_set_time,
.alarm_irq_enable = hym8563_rtc_alarm_irq_enable,
.read_alarm = hym8563_rtc_read_alarm,
.set_alarm = hym8563_rtc_set_alarm,
};
/*
* Handling of the clkout
*/
#ifdef CONFIG_COMMON_CLK
#define clkout_hw_to_hym8563(_hw) container_of(_hw, struct hym8563, clkout_hw)
static int clkout_rates[] = {
32768,
1024,
32,
1,
};
static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw);
struct i2c_client *client = hym8563->client;
int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
if (ret < 0 || ret & HYM8563_CLKOUT_DISABLE)
return 0;
ret &= HYM8563_CLKOUT_MASK;
return clkout_rates[ret];
}
static long hym8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
int i;
for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
if (clkout_rates[i] <= rate)
return clkout_rates[i];
return 0;
}
static int hym8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw);
struct i2c_client *client = hym8563->client;
int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
int i;
if (ret < 0)
return ret;
for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
if (clkout_rates[i] == rate) {
ret &= ~HYM8563_CLKOUT_MASK;
ret |= i;
return i2c_smbus_write_byte_data(client,
HYM8563_CLKOUT, ret);
}
return -EINVAL;
}
static int hym8563_clkout_control(struct clk_hw *hw, bool enable)
{
struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw);
struct i2c_client *client = hym8563->client;
int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
if (ret < 0)
return ret;
if (enable)
ret &= ~HYM8563_CLKOUT_DISABLE;
else
ret |= HYM8563_CLKOUT_DISABLE;
return i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, ret);
}
static int hym8563_clkout_prepare(struct clk_hw *hw)
{
return hym8563_clkout_control(hw, 1);
}
static void hym8563_clkout_unprepare(struct clk_hw *hw)
{
hym8563_clkout_control(hw, 0);
}
static int hym8563_clkout_is_prepared(struct clk_hw *hw)
{
struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw);
struct i2c_client *client = hym8563->client;
int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
if (ret < 0)
return ret;
return !(ret & HYM8563_CLKOUT_DISABLE);
}
static const struct clk_ops hym8563_clkout_ops = {
.prepare = hym8563_clkout_prepare,
.unprepare = hym8563_clkout_unprepare,
.is_prepared = hym8563_clkout_is_prepared,
.recalc_rate = hym8563_clkout_recalc_rate,
.round_rate = hym8563_clkout_round_rate,
.set_rate = hym8563_clkout_set_rate,
};
static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
{
struct i2c_client *client = hym8563->client;
struct device_node *node = client->dev.of_node;
struct clk *clk;
struct clk_init_data init;
int ret;
ret = i2c_smbus_write_byte_data(client, HYM8563_CLKOUT,
HYM8563_CLKOUT_DISABLE);
if (ret < 0)
return ERR_PTR(ret);
init.name = "hym8563-clkout";
init.ops = &hym8563_clkout_ops;
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;
init.num_parents = 0;
hym8563->clkout_hw.init = &init;
/* register the clock */
clk = clk_register(&client->dev, &hym8563->clkout_hw);
if (!IS_ERR(clk))
of_clk_add_provider(node, of_clk_src_simple_get, clk);
return clk;
}
#endif
/*
* The alarm interrupt is implemented as a level-low interrupt in the
* hym8563, while the timer interrupt uses a falling edge.
* We don't use the timer at all, so the interrupt is requested to
* use the level-low trigger.
*/
static irqreturn_t hym8563_irq(int irq, void *dev_id)
{
struct hym8563 *hym8563 = (struct hym8563 *)dev_id;
struct i2c_client *client = hym8563->client;
struct mutex *lock = &hym8563->rtc->ops_lock;
int data, ret;
mutex_lock(lock);
/* Clear the alarm flag */
data = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
if (data < 0) {
dev_err(&client->dev, "%s: error reading i2c data %d\n",
__func__, data);
goto out;
}
data &= ~HYM8563_CTL2_AF;
ret = i2c_smbus_write_byte_data(client, HYM8563_CTL2, data);
if (ret < 0) {
dev_err(&client->dev, "%s: error writing i2c data %d\n",
__func__, ret);
}
out:
mutex_unlock(lock);
return IRQ_HANDLED;
}
static int hym8563_init_device(struct i2c_client *client)
{
int ret;
/* Clear stop flag if present */
ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1, 0);
if (ret < 0)
return ret;
ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
if (ret < 0)
return ret;
/* Disable alarm and timer interrupts */
ret &= ~HYM8563_CTL2_AIE;
ret &= ~HYM8563_CTL2_TIE;
/* Clear any pending alarm and timer flags */
if (ret & HYM8563_CTL2_AF)
ret &= ~HYM8563_CTL2_AF;
if (ret & HYM8563_CTL2_TF)
ret &= ~HYM8563_CTL2_TF;
ret &= ~HYM8563_CTL2_TI_TP;
return i2c_smbus_write_byte_data(client, HYM8563_CTL2, ret);
}
#ifdef CONFIG_PM_SLEEP
static int hym8563_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
int ret;
if (device_may_wakeup(dev)) {
ret = enable_irq_wake(client->irq);
if (ret) {
dev_err(dev, "enable_irq_wake failed, %d\n", ret);
return ret;
}
}
return 0;
}
static int hym8563_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
if (device_may_wakeup(dev))
disable_irq_wake(client->irq);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(hym8563_pm_ops, hym8563_suspend, hym8563_resume);
static int hym8563_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct hym8563 *hym8563;
int ret;
hym8563 = devm_kzalloc(&client->dev, sizeof(*hym8563), GFP_KERNEL);
if (!hym8563)
return -ENOMEM;
hym8563->client = client;
i2c_set_clientdata(client, hym8563);
device_set_wakeup_capable(&client->dev, true);
ret = hym8563_init_device(client);
if (ret) {
dev_err(&client->dev, "could not init device, %d\n", ret);
return ret;
}
ret = devm_request_threaded_irq(&client->dev, client->irq,
NULL, hym8563_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
client->name, hym8563);
if (ret < 0) {
dev_err(&client->dev, "irq %d request failed, %d\n",
client->irq, ret);
return ret;
}
/* check state of calendar information */
ret = i2c_smbus_read_byte_data(client, HYM8563_SEC);
if (ret < 0)
return ret;
hym8563->valid = !(ret & HYM8563_SEC_VL);
dev_dbg(&client->dev, "rtc information is %s\n",
hym8563->valid ? "valid" : "invalid");
hym8563->rtc = devm_rtc_device_register(&client->dev, client->name,
&hym8563_rtc_ops, THIS_MODULE);
if (IS_ERR(hym8563->rtc))
return PTR_ERR(hym8563->rtc);
#ifdef CONFIG_COMMON_CLK
hym8563_clkout_register_clk(hym8563);
#endif
return 0;
}
static const struct i2c_device_id hym8563_id[] = {
{ "hym8563", 0 },
{},
};
MODULE_DEVICE_TABLE(i2c, hym8563_id);
static struct of_device_id hym8563_dt_idtable[] = {
{ .compatible = "haoyu,hym8563" },
{},
};
MODULE_DEVICE_TABLE(of, hym8563_dt_idtable);
static struct i2c_driver hym8563_driver = {
.driver = {
.name = "rtc-hym8563",
.owner = THIS_MODULE,
.pm = &hym8563_pm_ops,
.of_match_table = hym8563_dt_idtable,
},
.probe = hym8563_probe,
.id_table = hym8563_id,
};
module_i2c_driver(hym8563_driver);
MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
MODULE_DESCRIPTION("HYM8563 RTC driver");
MODULE_LICENSE("GPL");

View file

@ -51,7 +51,7 @@ static irqreturn_t max8907_irq_handler(int irq, void *data)
{
struct max8907_rtc *rtc = data;
regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0);
regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0);
rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
@ -64,7 +64,7 @@ static void regs_to_tm(u8 *regs, struct rtc_time *tm)
bcd2bin(regs[RTC_YEAR1]) - 1900;
tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1;
tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f);
tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07) - 1;
tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07);
if (regs[RTC_HOUR] & HOUR_12) {
tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f);
if (tm->tm_hour == 12)
@ -88,7 +88,7 @@ static void tm_to_regs(struct rtc_time *tm, u8 *regs)
regs[RTC_YEAR1] = bin2bcd(low);
regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
regs[RTC_DATE] = bin2bcd(tm->tm_mday);
regs[RTC_WEEKDAY] = tm->tm_wday + 1;
regs[RTC_WEEKDAY] = tm->tm_wday;
regs[RTC_HOUR] = bin2bcd(tm->tm_hour);
regs[RTC_MIN] = bin2bcd(tm->tm_min);
regs[RTC_SEC] = bin2bcd(tm->tm_sec);
@ -153,7 +153,7 @@ static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
tm_to_regs(&alrm->time, regs);
/* Disable alarm while we update the target time */
ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0);
ret = regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0);
if (ret < 0)
return ret;
@ -163,8 +163,7 @@ static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
if (alrm->enabled)
ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL,
0x7f, 0x7f);
ret = regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x77);
return ret;
}

View file

@ -391,11 +391,13 @@ static int mxc_rtc_probe(struct platform_device *pdev)
pdata->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pdata->clk)) {
dev_err(&pdev->dev, "unable to get clock!\n");
ret = PTR_ERR(pdata->clk);
goto exit_free_pdata;
return PTR_ERR(pdata->clk);
}
clk_prepare_enable(pdata->clk);
ret = clk_prepare_enable(pdata->clk);
if (ret)
return ret;
rate = clk_get_rate(pdata->clk);
if (rate == 32768)
@ -447,8 +449,6 @@ static int mxc_rtc_probe(struct platform_device *pdev)
exit_put_clk:
clk_disable_unprepare(pdata->clk);
exit_free_pdata:
return ret;
}

View file

@ -197,10 +197,7 @@ static int pcf2127_probe(struct i2c_client *client,
pcf2127_driver.driver.name,
&pcf2127_rtc_ops, THIS_MODULE);
if (IS_ERR(pcf2127->rtc))
return PTR_ERR(pcf2127->rtc);
return 0;
return PTR_ERR_OR_ZERO(pcf2127->rtc);
}
static const struct i2c_device_id pcf2127_id[] = {

View file

@ -52,8 +52,45 @@
#define RX8581_CTRL_STOP 0x02 /* STOP bit */
#define RX8581_CTRL_RESET 0x01 /* RESET bit */
struct rx8581 {
struct i2c_client *client;
struct rtc_device *rtc;
s32 (*read_block_data)(const struct i2c_client *client, u8 command,
u8 length, u8 *values);
s32 (*write_block_data)(const struct i2c_client *client, u8 command,
u8 length, const u8 *values);
};
static struct i2c_driver rx8581_driver;
static int rx8581_read_block_data(const struct i2c_client *client, u8 command,
u8 length, u8 *values)
{
s32 i, data;
for (i = 0; i < length; i++) {
data = i2c_smbus_read_byte_data(client, command + i);
if (data < 0)
return data;
values[i] = data;
}
return i;
}
static int rx8581_write_block_data(const struct i2c_client *client, u8 command,
u8 length, const u8 *values)
{
s32 i, ret;
for (i = 0; i < length; i++) {
ret = i2c_smbus_write_byte_data(client, command + i,
values[i]);
if (ret < 0)
return ret;
}
return length;
}
/*
* In the routines that deal directly with the rx8581 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@ -62,6 +99,7 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
unsigned char date[7];
int data, err;
struct rx8581 *rx8581 = i2c_get_clientdata(client);
/* First we ensure that the "update flag" is not set, we read the
* time and date then re-read the "update flag". If the update flag
@ -80,14 +118,13 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm)
err = i2c_smbus_write_byte_data(client,
RX8581_REG_FLAG, (data & ~RX8581_FLAG_UF));
if (err != 0) {
dev_err(&client->dev, "Unable to write device "
"flags\n");
dev_err(&client->dev, "Unable to write device flags\n");
return -EIO;
}
}
/* Now read time and date */
err = i2c_smbus_read_i2c_block_data(client, RX8581_REG_SC,
err = rx8581->read_block_data(client, RX8581_REG_SC,
7, date);
if (err < 0) {
dev_err(&client->dev, "Unable to read date\n");
@ -140,6 +177,7 @@ static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
int data, err;
unsigned char buf[7];
struct rx8581 *rx8581 = i2c_get_clientdata(client);
dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
@ -176,7 +214,7 @@ static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm)
}
/* write register's data */
err = i2c_smbus_write_i2c_block_data(client, RX8581_REG_SC, 7, buf);
err = rx8581->write_block_data(client, RX8581_REG_SC, 7, buf);
if (err < 0) {
dev_err(&client->dev, "Unable to write to date registers\n");
return -EIO;
@ -231,22 +269,39 @@ static const struct rtc_class_ops rx8581_rtc_ops = {
static int rx8581_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct rtc_device *rtc;
struct rx8581 *rx8581;
dev_dbg(&client->dev, "%s\n", __func__);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)
&& !i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO;
rx8581 = devm_kzalloc(&client->dev, sizeof(struct rx8581), GFP_KERNEL);
if (!rx8581)
return -ENOMEM;
i2c_set_clientdata(client, rx8581);
rx8581->client = client;
if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
rx8581->read_block_data = i2c_smbus_read_i2c_block_data;
rx8581->write_block_data = i2c_smbus_write_i2c_block_data;
} else {
rx8581->read_block_data = rx8581_read_block_data;
rx8581->write_block_data = rx8581_write_block_data;
}
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
rtc = devm_rtc_device_register(&client->dev, rx8581_driver.driver.name,
&rx8581_rtc_ops, THIS_MODULE);
rx8581->rtc = devm_rtc_device_register(&client->dev,
rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
i2c_set_clientdata(client, rtc);
if (IS_ERR(rx8581->rtc)) {
dev_err(&client->dev,
"unable to register the class device\n");
return PTR_ERR(rx8581->rtc);
}
return 0;
}

View file

@ -639,6 +639,7 @@ static void s5m_rtc_shutdown(struct platform_device *pdev)
s5m_rtc_enable_smpl(info, false);
}
#ifdef CONFIG_PM_SLEEP
static int s5m_rtc_resume(struct device *dev)
{
struct s5m_rtc_info *info = dev_get_drvdata(dev);
@ -660,6 +661,7 @@ static int s5m_rtc_suspend(struct device *dev)
return ret;
}
#endif /* CONFIG_PM_SLEEP */
static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);

View file

@ -479,7 +479,7 @@ static int twl_rtc_probe(struct platform_device *pdev)
u8 rd_reg;
if (irq <= 0)
goto out1;
return ret;
/* Initialize the register map */
if (twl_class_is_4030())
@ -489,7 +489,7 @@ static int twl_rtc_probe(struct platform_device *pdev)
ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
if (ret < 0)
goto out1;
return ret;
if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
dev_warn(&pdev->dev, "Power up reset detected.\n");
@ -500,7 +500,7 @@ static int twl_rtc_probe(struct platform_device *pdev)
/* Clear RTC Power up reset and pending alarm interrupts */
ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
if (ret < 0)
goto out1;
return ret;
if (twl_class_is_6030()) {
twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
@ -512,7 +512,7 @@ static int twl_rtc_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Enabling TWL-RTC\n");
ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG);
if (ret < 0)
goto out1;
return ret;
/* ensure interrupts are disabled, bootloaders can be strange */
ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG);
@ -522,34 +522,29 @@ static int twl_rtc_probe(struct platform_device *pdev)
/* init cached IRQ enable bits */
ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
if (ret < 0)
goto out1;
return ret;
device_init_wakeup(&pdev->dev, 1);
rtc = rtc_device_register(pdev->name,
&pdev->dev, &twl_rtc_ops, THIS_MODULE);
rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&twl_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
ret = PTR_ERR(rtc);
dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
PTR_ERR(rtc));
goto out1;
return PTR_ERR(rtc);
}
ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dev_name(&rtc->dev), rtc);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
twl_rtc_interrupt,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dev_name(&rtc->dev), rtc);
if (ret < 0) {
dev_err(&pdev->dev, "IRQ is not free.\n");
goto out2;
return ret;
}
platform_set_drvdata(pdev, rtc);
return 0;
out2:
rtc_device_unregister(rtc);
out1:
return ret;
}
/*
@ -559,9 +554,6 @@ static int twl_rtc_probe(struct platform_device *pdev)
static int twl_rtc_remove(struct platform_device *pdev)
{
/* leave rtc running, but disable irqs */
struct rtc_device *rtc = platform_get_drvdata(pdev);
int irq = platform_get_irq(pdev, 0);
mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
if (twl_class_is_6030()) {
@ -571,10 +563,6 @@ static int twl_rtc_remove(struct platform_device *pdev)
REG_INT_MSK_STS_A);
}
free_irq(irq, rtc);
rtc_device_unregister(rtc);
return 0;
}

View file

@ -293,7 +293,7 @@ static int rtc_probe(struct platform_device *pdev)
if (!res)
return -EBUSY;
rtc1_base = ioremap(res->start, resource_size(res));
rtc1_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (!rtc1_base)
return -EBUSY;
@ -303,13 +303,14 @@ static int rtc_probe(struct platform_device *pdev)
goto err_rtc1_iounmap;
}
rtc2_base = ioremap(res->start, resource_size(res));
rtc2_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (!rtc2_base) {
retval = -EBUSY;
goto err_rtc1_iounmap;
}
rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE);
rtc = devm_rtc_device_register(&pdev->dev, rtc_name, &vr41xx_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtc)) {
retval = PTR_ERR(rtc);
goto err_iounmap_all;
@ -330,24 +331,24 @@ static int rtc_probe(struct platform_device *pdev)
aie_irq = platform_get_irq(pdev, 0);
if (aie_irq <= 0) {
retval = -EBUSY;
goto err_device_unregister;
goto err_iounmap_all;
}
retval = request_irq(aie_irq, elapsedtime_interrupt, 0,
"elapsed_time", pdev);
retval = devm_request_irq(&pdev->dev, aie_irq, elapsedtime_interrupt, 0,
"elapsed_time", pdev);
if (retval < 0)
goto err_device_unregister;
goto err_iounmap_all;
pie_irq = platform_get_irq(pdev, 1);
if (pie_irq <= 0) {
retval = -EBUSY;
goto err_free_irq;
goto err_iounmap_all;
}
retval = request_irq(pie_irq, rtclong1_interrupt, 0,
"rtclong1", pdev);
retval = devm_request_irq(&pdev->dev, pie_irq, rtclong1_interrupt, 0,
"rtclong1", pdev);
if (retval < 0)
goto err_free_irq;
goto err_iounmap_all;
platform_set_drvdata(pdev, rtc);
@ -358,47 +359,20 @@ static int rtc_probe(struct platform_device *pdev)
return 0;
err_free_irq:
free_irq(aie_irq, pdev);
err_device_unregister:
rtc_device_unregister(rtc);
err_iounmap_all:
iounmap(rtc2_base);
rtc2_base = NULL;
err_rtc1_iounmap:
iounmap(rtc1_base);
rtc1_base = NULL;
return retval;
}
static int rtc_remove(struct platform_device *pdev)
{
struct rtc_device *rtc;
rtc = platform_get_drvdata(pdev);
if (rtc)
rtc_device_unregister(rtc);
free_irq(aie_irq, pdev);
free_irq(pie_irq, pdev);
if (rtc1_base)
iounmap(rtc1_base);
if (rtc2_base)
iounmap(rtc2_base);
return 0;
}
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:RTC");
static struct platform_driver rtc_platform_driver = {
.probe = rtc_probe,
.remove = rtc_remove,
.driver = {
.name = rtc_name,
.owner = THIS_MODULE,

View file

@ -357,11 +357,13 @@ static int default_lcd_on = 1;
static bool mtrr = true;
#endif
#ifdef CONFIG_FB_ATY128_BACKLIGHT
#ifdef CONFIG_PMAC_BACKLIGHT
static int backlight = 1;
#else
static int backlight = 0;
#endif
#endif
/* PLL constants */
struct aty128_constants {
@ -1671,7 +1673,9 @@ static int aty128fb_setup(char *options)
default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
continue;
} else if (!strncmp(this_opt, "backlight:", 10)) {
#ifdef CONFIG_FB_ATY128_BACKLIGHT
backlight = simple_strtoul(this_opt+10, NULL, 0);
#endif
continue;
}
#ifdef CONFIG_MTRR

View file

@ -110,8 +110,8 @@ static int hp680bl_probe(struct platform_device *pdev)
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = HP680_MAX_INTENSITY;
bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
&hp680bl_ops, &props);
bd = devm_backlight_device_register(&pdev->dev, "hp680-bl", &pdev->dev,
NULL, &hp680bl_ops, &props);
if (IS_ERR(bd))
return PTR_ERR(bd);
@ -131,8 +131,6 @@ static int hp680bl_remove(struct platform_device *pdev)
bd->props.power = 0;
hp680bl_send_intensity(bd);
backlight_device_unregister(bd);
return 0;
}

View file

@ -115,9 +115,10 @@ static int jornada_bl_probe(struct platform_device *pdev)
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = BL_MAX_BRIGHT;
bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
&jornada_bl_ops, &props);
bd = devm_backlight_device_register(&pdev->dev, S1D_DEVICENAME,
&pdev->dev, NULL, &jornada_bl_ops,
&props);
if (IS_ERR(bd)) {
ret = PTR_ERR(bd);
dev_err(&pdev->dev, "failed to register device, err=%x\n", ret);
@ -139,18 +140,8 @@ static int jornada_bl_probe(struct platform_device *pdev)
return 0;
}
static int jornada_bl_remove(struct platform_device *pdev)
{
struct backlight_device *bd = platform_get_drvdata(pdev);
backlight_device_unregister(bd);
return 0;
}
static struct platform_driver jornada_bl_driver = {
.probe = jornada_bl_probe,
.remove = jornada_bl_remove,
.driver = {
.name = "jornada_bl",
},

View file

@ -100,7 +100,8 @@ static int jornada_lcd_probe(struct platform_device *pdev)
struct lcd_device *lcd_device;
int ret;
lcd_device = lcd_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_lcd_props);
lcd_device = devm_lcd_device_register(&pdev->dev, S1D_DEVICENAME,
&pdev->dev, NULL, &jornada_lcd_props);
if (IS_ERR(lcd_device)) {
ret = PTR_ERR(lcd_device);
@ -119,18 +120,8 @@ static int jornada_lcd_probe(struct platform_device *pdev)
return 0;
}
static int jornada_lcd_remove(struct platform_device *pdev)
{
struct lcd_device *lcd_device = platform_get_drvdata(pdev);
lcd_device_unregister(lcd_device);
return 0;
}
static struct platform_driver jornada_lcd_driver = {
.probe = jornada_lcd_probe,
.remove = jornada_lcd_remove,
.driver = {
.name = "jornada_lcd",
},

View file

@ -78,7 +78,7 @@ static struct kb3886bl_machinfo *bl_machinfo;
static unsigned long kb3886bl_flags;
#define KB3886BL_SUSPENDED 0x01
static struct dmi_system_id __initdata kb3886bl_device_table[] = {
static struct dmi_system_id kb3886bl_device_table[] __initdata = {
{
.ident = "Sahara Touch-iT",
.matches = {

View file

@ -223,8 +223,8 @@ static int l4f00242t03_probe(struct spi_device *spi)
return PTR_ERR(priv->core_reg);
}
priv->ld = lcd_device_register("l4f00242t03",
&spi->dev, priv, &l4f_ops);
priv->ld = devm_lcd_device_register(&spi->dev, "l4f00242t03", &spi->dev,
priv, &l4f_ops);
if (IS_ERR(priv->ld))
return PTR_ERR(priv->ld);
@ -243,8 +243,6 @@ static int l4f00242t03_remove(struct spi_device *spi)
struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
lcd_device_unregister(priv->ld);
return 0;
}

View file

@ -125,7 +125,7 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
return false;
}
return (addr >= start && addr <= end);
return addr >= start && addr <= end;
}
static int lp8557_bl_off(struct lp855x *lp)

View file

@ -63,13 +63,13 @@ static struct lp8788_bl_config default_bl_config = {
static inline bool is_brightness_ctrl_by_pwm(enum lp8788_bl_ctrl_mode mode)
{
return (mode == LP8788_BL_COMB_PWM_BASED);
return mode == LP8788_BL_COMB_PWM_BASED;
}
static inline bool is_brightness_ctrl_by_register(enum lp8788_bl_ctrl_mode mode)
{
return (mode == LP8788_BL_REGISTER_ONLY ||
mode == LP8788_BL_COMB_REGISTER_BASED);
return mode == LP8788_BL_REGISTER_ONLY ||
mode == LP8788_BL_COMB_REGISTER_BASED;
}
static int lp8788_backlight_configure(struct lp8788_bl *bl)

View file

@ -146,8 +146,8 @@ static int omapbl_probe(struct platform_device *pdev)
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = OMAPBL_MAX_INTENSITY;
dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
&props);
dev = devm_backlight_device_register(&pdev->dev, "omap-bl", &pdev->dev,
bl, &omapbl_ops, &props);
if (IS_ERR(dev))
return PTR_ERR(dev);
@ -170,20 +170,10 @@ static int omapbl_probe(struct platform_device *pdev)
return 0;
}
static int omapbl_remove(struct platform_device *pdev)
{
struct backlight_device *dev = platform_get_drvdata(pdev);
backlight_device_unregister(dev);
return 0;
}
static SIMPLE_DEV_PM_OPS(omapbl_pm_ops, omapbl_suspend, omapbl_resume);
static struct platform_driver omapbl_driver = {
.probe = omapbl_probe,
.remove = omapbl_remove,
.driver = {
.name = "omap-bl",
.pm = &omapbl_pm_ops,

View file

@ -118,8 +118,9 @@ static int ot200_backlight_probe(struct platform_device *pdev)
props.brightness = 100;
props.type = BACKLIGHT_RAW;
bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data,
&ot200_backlight_ops, &props);
bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev),
&pdev->dev, data, &ot200_backlight_ops,
&props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
retval = PTR_ERR(bl);
@ -137,10 +138,6 @@ static int ot200_backlight_probe(struct platform_device *pdev)
static int ot200_backlight_remove(struct platform_device *pdev)
{
struct backlight_device *bl = platform_get_drvdata(pdev);
backlight_device_unregister(bl);
/* on module unload set brightness to 100% */
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);

View file

@ -105,8 +105,9 @@ static int tosa_bl_probe(struct i2c_client *client,
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = 512 - 1;
data->bl = backlight_device_register("tosa-bl", &client->dev, data,
&bl_ops, &props);
data->bl = devm_backlight_device_register(&client->dev, "tosa-bl",
&client->dev, data, &bl_ops,
&props);
if (IS_ERR(data->bl)) {
ret = PTR_ERR(data->bl);
goto err_reg;
@ -128,9 +129,7 @@ static int tosa_bl_remove(struct i2c_client *client)
{
struct tosa_bl_data *data = i2c_get_clientdata(client);
backlight_device_unregister(data->bl);
data->bl = NULL;
return 0;
}

View file

@ -206,8 +206,8 @@ static int tosa_lcd_probe(struct spi_device *spi)
tosa_lcd_tg_on(data);
data->lcd = lcd_device_register("tosa-lcd", &spi->dev, data,
&tosa_lcd_ops);
data->lcd = devm_lcd_device_register(&spi->dev, "tosa-lcd", &spi->dev,
data, &tosa_lcd_ops);
if (IS_ERR(data->lcd)) {
ret = PTR_ERR(data->lcd);
@ -226,8 +226,6 @@ static int tosa_lcd_remove(struct spi_device *spi)
{
struct tosa_lcd_data *data = spi_get_drvdata(spi);
lcd_device_unregister(data->lcd);
if (data->i2c)
i2c_unregister_device(data->i2c);

View file

@ -762,7 +762,8 @@ static int vlynq_remove(struct platform_device *pdev)
device_unregister(&dev->dev);
iounmap(dev->local);
release_mem_region(dev->regs_start, dev->regs_end - dev->regs_start);
release_mem_region(dev->regs_start,
dev->regs_end - dev->regs_start + 1);
kfree(dev);

View file

@ -18,10 +18,31 @@
#include <linux/of_gpio.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/delay.h>
#include "../w1.h"
#include "../w1_int.h"
static u8 w1_gpio_set_pullup(void *data, int delay)
{
struct w1_gpio_platform_data *pdata = data;
if (delay) {
pdata->pullup_duration = delay;
} else {
if (pdata->pullup_duration) {
gpio_direction_output(pdata->pin, 1);
msleep(pdata->pullup_duration);
gpio_direction_input(pdata->pin);
}
pdata->pullup_duration = 0;
}
return 0;
}
static void w1_gpio_write_bit_dir(void *data, u8 bit)
{
struct w1_gpio_platform_data *pdata = data;
@ -132,6 +153,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
} else {
gpio_direction_input(pdata->pin);
master->write_bit = w1_gpio_write_bit_dir;
master->set_pullup = w1_gpio_set_pullup;
}
err = w1_add_master_device(master);

View file

@ -117,18 +117,6 @@ int w1_add_master_device(struct w1_bus_master *master)
printk(KERN_ERR "w1_add_master_device: invalid function set\n");
return(-EINVAL);
}
/* While it would be electrically possible to make a device that
* generated a strong pullup in bit bang mode, only hardware that
* controls 1-wire time frames are even expected to support a strong
* pullup. w1_io.c would need to support calling set_pullup before
* the last write_bit operation of a w1_write_8 which it currently
* doesn't.
*/
if (!master->write_byte && !master->touch_bit && master->set_pullup) {
printk(KERN_ERR "w1_add_master_device: set_pullup requires "
"write_byte or touch_bit, disabling\n");
master->set_pullup = NULL;
}
/* Lock until the device is added (or not) to w1_masters. */
mutex_lock(&w1_mlock);

View file

@ -104,7 +104,7 @@ struct autofs_sb_info {
u32 magic;
int pipefd;
struct file *pipe;
pid_t oz_pgrp;
struct pid *oz_pgrp;
int catatonic;
int version;
int sub_version;
@ -140,7 +140,7 @@ static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry)
filesystem without "magic".) */
static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp;
return sbi->catatonic || task_pgrp(current) == sbi->oz_pgrp;
}
/* Does a dentry have some pending activity? */

View file

@ -346,6 +346,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
{
int pipefd;
int err = 0;
struct pid *new_pid = NULL;
if (param->setpipefd.pipefd == -1)
return -EINVAL;
@ -357,7 +358,17 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
mutex_unlock(&sbi->wq_mutex);
return -EBUSY;
} else {
struct file *pipe = fget(pipefd);
struct file *pipe;
new_pid = get_task_pid(current, PIDTYPE_PGID);
if (ns_of_pid(new_pid) != ns_of_pid(sbi->oz_pgrp)) {
AUTOFS_WARN("Not allowed to change PID namespace");
err = -EINVAL;
goto out;
}
pipe = fget(pipefd);
if (!pipe) {
err = -EBADF;
goto out;
@ -367,12 +378,13 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
fput(pipe);
goto out;
}
sbi->oz_pgrp = task_pgrp_nr(current);
swap(sbi->oz_pgrp, new_pid);
sbi->pipefd = pipefd;
sbi->pipe = pipe;
sbi->catatonic = 0;
}
out:
put_pid(new_pid);
mutex_unlock(&sbi->wq_mutex);
return err;
}

View file

@ -402,6 +402,20 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
goto next;
}
if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
DPRINTK("checking symlink %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
/*
* A symlink can't be "busy" in the usual sense so
* just check last used for expire timeout.
*/
if (autofs4_can_expire(dentry, timeout, do_now)) {
expired = dentry;
goto found;
}
goto next;
}
if (simple_empty(dentry))
goto next;

View file

@ -56,8 +56,11 @@ void autofs4_kill_sb(struct super_block *sb)
* just call kill_anon_super when we are called from
* deactivate_super.
*/
if (sbi) /* Free wait queues, close pipe */
if (sbi) {
/* Free wait queues, close pipe */
autofs4_catatonic_mode(sbi);
put_pid(sbi->oz_pgrp);
}
DPRINTK("shutting down");
kill_litter_super(sb);
@ -80,7 +83,7 @@ static int autofs4_show_options(struct seq_file *m, struct dentry *root)
if (!gid_eq(root_inode->i_gid, GLOBAL_ROOT_GID))
seq_printf(m, ",gid=%u",
from_kgid_munged(&init_user_ns, root_inode->i_gid));
seq_printf(m, ",pgrp=%d", sbi->oz_pgrp);
seq_printf(m, ",pgrp=%d", pid_vnr(sbi->oz_pgrp));
seq_printf(m, ",timeout=%lu", sbi->exp_timeout/HZ);
seq_printf(m, ",minproto=%d", sbi->min_proto);
seq_printf(m, ",maxproto=%d", sbi->max_proto);
@ -124,7 +127,8 @@ static const match_table_t tokens = {
};
static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid,
pid_t *pgrp, unsigned int *type, int *minproto, int *maxproto)
int *pgrp, bool *pgrp_set, unsigned int *type,
int *minproto, int *maxproto)
{
char *p;
substring_t args[MAX_OPT_ARGS];
@ -132,7 +136,6 @@ static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid,
*uid = current_uid();
*gid = current_gid();
*pgrp = task_pgrp_nr(current);
*minproto = AUTOFS_MIN_PROTO_VERSION;
*maxproto = AUTOFS_MAX_PROTO_VERSION;
@ -171,6 +174,7 @@ static int parse_options(char *options, int *pipefd, kuid_t *uid, kgid_t *gid,
if (match_int(args, &option))
return 1;
*pgrp = option;
*pgrp_set = true;
break;
case Opt_minproto:
if (match_int(args, &option))
@ -206,10 +210,13 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
int pipefd;
struct autofs_sb_info *sbi;
struct autofs_info *ino;
int pgrp;
bool pgrp_set = false;
int ret = -EINVAL;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
goto fail_unlock;
return -ENOMEM;
DPRINTK("starting up, sbi = %p",sbi);
s->s_fs_info = sbi;
@ -218,7 +225,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
sbi->pipe = NULL;
sbi->catatonic = 1;
sbi->exp_timeout = 0;
sbi->oz_pgrp = task_pgrp_nr(current);
sbi->oz_pgrp = NULL;
sbi->sb = s;
sbi->version = 0;
sbi->sub_version = 0;
@ -243,8 +250,10 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
* Get the root inode and dentry, but defer checking for errors.
*/
ino = autofs4_new_ino(sbi);
if (!ino)
if (!ino) {
ret = -ENOMEM;
goto fail_free;
}
root_inode = autofs4_get_inode(s, S_IFDIR | 0755);
root = d_make_root(root_inode);
if (!root)
@ -255,12 +264,23 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
/* Can this call block? */
if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid,
&sbi->oz_pgrp, &sbi->type, &sbi->min_proto,
&sbi->max_proto)) {
&pgrp, &pgrp_set, &sbi->type, &sbi->min_proto,
&sbi->max_proto)) {
printk("autofs: called with bogus options\n");
goto fail_dput;
}
if (pgrp_set) {
sbi->oz_pgrp = find_get_pid(pgrp);
if (!sbi->oz_pgrp) {
pr_warn("autofs: could not find process group %d\n",
pgrp);
goto fail_dput;
}
} else {
sbi->oz_pgrp = get_task_pid(current, PIDTYPE_PGID);
}
if (autofs_type_trigger(sbi->type))
__managed_dentry_set_managed(root);
@ -284,14 +304,15 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
sbi->version = sbi->max_proto;
sbi->sub_version = AUTOFS_PROTO_SUBVERSION;
DPRINTK("pipe fd = %d, pgrp = %u", pipefd, sbi->oz_pgrp);
DPRINTK("pipe fd = %d, pgrp = %u", pipefd, pid_nr(sbi->oz_pgrp));
pipe = fget(pipefd);
if (!pipe) {
printk("autofs: could not open pipe file descriptor\n");
goto fail_dput;
}
if (autofs_prepare_pipe(pipe) < 0)
ret = autofs_prepare_pipe(pipe);
if (ret < 0)
goto fail_fput;
sbi->pipe = pipe;
sbi->pipefd = pipefd;
@ -316,10 +337,10 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
fail_ino:
kfree(ino);
fail_free:
put_pid(sbi->oz_pgrp);
kfree(sbi);
s->s_fs_info = NULL;
fail_unlock:
return -EINVAL;
return ret;
}
struct inode *autofs4_get_inode(struct super_block *sb, umode_t mode)

View file

@ -558,7 +558,7 @@ static int autofs4_dir_symlink(struct inode *dir,
dget(dentry);
atomic_inc(&ino->count);
p_ino = autofs4_dentry_ino(dentry->d_parent);
if (p_ino && dentry->d_parent != dentry)
if (p_ino && !IS_ROOT(dentry))
atomic_inc(&p_ino->count);
dir->i_mtime = CURRENT_TIME;
@ -593,7 +593,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
if (atomic_dec_and_test(&ino->count)) {
p_ino = autofs4_dentry_ino(dentry->d_parent);
if (p_ino && dentry->d_parent != dentry)
if (p_ino && !IS_ROOT(dentry))
atomic_dec(&p_ino->count);
}
dput(ino->dentry);
@ -732,7 +732,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t m
dget(dentry);
atomic_inc(&ino->count);
p_ino = autofs4_dentry_ino(dentry->d_parent);
if (p_ino && dentry->d_parent != dentry)
if (p_ino && !IS_ROOT(dentry))
atomic_inc(&p_ino->count);
inc_nlink(dir);
dir->i_mtime = CURRENT_TIME;

View file

@ -14,6 +14,10 @@
static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
if (ino && !autofs4_oz_mode(sbi))
ino->last_used = jiffies;
nd_set_link(nd, dentry->d_inode->i_private);
return NULL;
}

View file

@ -347,11 +347,23 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
struct qstr qstr;
char *name;
int status, ret, type;
pid_t pid;
pid_t tgid;
/* In catatonic mode, we don't wait for nobody */
if (sbi->catatonic)
return -ENOENT;
/*
* Try translating pids to the namespace of the daemon.
*
* Zero means failure: we are in an unrelated pid namespace.
*/
pid = task_pid_nr_ns(current, ns_of_pid(sbi->oz_pgrp));
tgid = task_tgid_nr_ns(current, ns_of_pid(sbi->oz_pgrp));
if (pid == 0 || tgid == 0)
return -ENOENT;
if (!dentry->d_inode) {
/*
* A wait for a negative dentry is invalid for certain
@ -417,8 +429,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
wq->ino = autofs4_get_ino(sbi);
wq->uid = current_uid();
wq->gid = current_gid();
wq->pid = current->pid;
wq->tgid = current->tgid;
wq->pid = pid;
wq->tgid = tgid;
wq->status = -EINTR; /* Status return if interrupted */
wq->wait_ctr = 2;

View file

@ -543,9 +543,6 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
* libraries. There is no binary dependent code anywhere else.
*/
#define INTERPRETER_NONE 0
#define INTERPRETER_ELF 2
#ifndef STACK_RND_MASK
#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
#endif

View file

@ -40,7 +40,6 @@
#include <trace/events/task.h>
#include "internal.h"
#include "coredump.h"
#include <trace/events/sched.h>

View file

@ -1,6 +0,0 @@
#ifndef _FS_COREDUMP_H
#define _FS_COREDUMP_H
extern int __get_dumpable(unsigned long mm_flags);
#endif

120
fs/exec.c
View file

@ -62,7 +62,6 @@
#include <trace/events/task.h>
#include "internal.h"
#include "coredump.h"
#include <trace/events/sched.h>
@ -843,7 +842,6 @@ static int exec_mmap(struct mm_struct *mm)
tsk->active_mm = mm;
activate_mm(active_mm, mm);
task_unlock(tsk);
arch_pick_mmap_layout(mm);
if (old_mm) {
up_read(&old_mm->mmap_sem);
BUG_ON(active_mm != old_mm);
@ -1088,8 +1086,8 @@ int flush_old_exec(struct linux_binprm * bprm)
bprm->mm = NULL; /* We're using it now */
set_fs(USER_DS);
current->flags &=
~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | PF_NOFREEZE);
current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD |
PF_NOFREEZE | PF_NO_SETAFFINITY);
flush_thread();
current->personality &= ~bprm->per_clear;
@ -1139,9 +1137,7 @@ void setup_new_exec(struct linux_binprm * bprm)
/* An exec changes our domain. We are no longer part of the thread
group */
current->self_exec_id++;
flush_signal_handlers(current, 0);
do_close_on_exec(current->files);
}
@ -1173,6 +1169,10 @@ void free_bprm(struct linux_binprm *bprm)
mutex_unlock(&current->signal->cred_guard_mutex);
abort_creds(bprm->cred);
}
if (bprm->file) {
allow_write_access(bprm->file);
fput(bprm->file);
}
/* If a binfmt changed the interp, free it. */
if (bprm->interp != bprm->filename)
kfree(bprm->interp);
@ -1224,11 +1224,10 @@ EXPORT_SYMBOL(install_exec_creds);
* - the caller must hold ->cred_guard_mutex to protect against
* PTRACE_ATTACH
*/
static int check_unsafe_exec(struct linux_binprm *bprm)
static void check_unsafe_exec(struct linux_binprm *bprm)
{
struct task_struct *p = current, *t;
unsigned n_fs;
int res = 0;
if (p->ptrace) {
if (p->ptrace & PT_PTRACE_CAP)
@ -1244,31 +1243,25 @@ static int check_unsafe_exec(struct linux_binprm *bprm)
if (current->no_new_privs)
bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;
t = p;
n_fs = 1;
spin_lock(&p->fs->lock);
rcu_read_lock();
for (t = next_thread(p); t != p; t = next_thread(t)) {
while_each_thread(p, t) {
if (t->fs == p->fs)
n_fs++;
}
rcu_read_unlock();
if (p->fs->users > n_fs) {
if (p->fs->users > n_fs)
bprm->unsafe |= LSM_UNSAFE_SHARE;
} else {
res = -EAGAIN;
if (!p->fs->in_exec) {
p->fs->in_exec = 1;
res = 1;
}
}
else
p->fs->in_exec = 1;
spin_unlock(&p->fs->lock);
return res;
}
/*
* Fill the binprm structure from the inode.
/*
* Fill the binprm structure from the inode.
* Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
*
* This may be called multiple times for binary chains (scripts for example).
@ -1430,14 +1423,7 @@ static int exec_binprm(struct linux_binprm *bprm)
audit_bprm(bprm);
trace_sched_process_exec(current, old_pid, bprm);
ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
current->did_exec = 1;
proc_exec_connector(current);
if (bprm->file) {
allow_write_access(bprm->file);
fput(bprm->file);
bprm->file = NULL; /* to catch use-after-free */
}
}
return ret;
@ -1453,7 +1439,6 @@ static int do_execve_common(const char *filename,
struct linux_binprm *bprm;
struct file *file;
struct files_struct *displaced;
bool clear_in_exec;
int retval;
/*
@ -1485,10 +1470,7 @@ static int do_execve_common(const char *filename,
if (retval)
goto out_free;
retval = check_unsafe_exec(bprm);
if (retval < 0)
goto out_free;
clear_in_exec = retval;
check_unsafe_exec(bprm);
current->in_execve = 1;
file = open_exec(filename);
@ -1504,7 +1486,7 @@ static int do_execve_common(const char *filename,
retval = bprm_mm_init(bprm);
if (retval)
goto out_file;
goto out_unmark;
bprm->argc = count(argv, MAX_ARG_STRINGS);
if ((retval = bprm->argc) < 0)
@ -1551,15 +1533,8 @@ static int do_execve_common(const char *filename,
mmput(bprm->mm);
}
out_file:
if (bprm->file) {
allow_write_access(bprm->file);
fput(bprm->file);
}
out_unmark:
if (clear_in_exec)
current->fs->in_exec = 0;
current->fs->in_exec = 0;
current->in_execve = 0;
out_free:
@ -1609,67 +1584,22 @@ void set_binfmt(struct linux_binfmt *new)
if (new)
__module_get(new->module);
}
EXPORT_SYMBOL(set_binfmt);
/*
* set_dumpable converts traditional three-value dumpable to two flags and
* stores them into mm->flags. It modifies lower two bits of mm->flags, but
* these bits are not changed atomically. So get_dumpable can observe the
* intermediate state. To avoid doing unexpected behavior, get get_dumpable
* return either old dumpable or new one by paying attention to the order of
* modifying the bits.
*
* dumpable | mm->flags (binary)
* old new | initial interim final
* ---------+-----------------------
* 0 1 | 00 01 01
* 0 2 | 00 10(*) 11
* 1 0 | 01 00 00
* 1 2 | 01 11 11
* 2 0 | 11 10(*) 00
* 2 1 | 11 11 01
*
* (*) get_dumpable regards interim value of 10 as 11.
* set_dumpable stores three-value SUID_DUMP_* into mm->flags.
*/
void set_dumpable(struct mm_struct *mm, int value)
{
switch (value) {
case SUID_DUMP_DISABLE:
clear_bit(MMF_DUMPABLE, &mm->flags);
smp_wmb();
clear_bit(MMF_DUMP_SECURELY, &mm->flags);
break;
case SUID_DUMP_USER:
set_bit(MMF_DUMPABLE, &mm->flags);
smp_wmb();
clear_bit(MMF_DUMP_SECURELY, &mm->flags);
break;
case SUID_DUMP_ROOT:
set_bit(MMF_DUMP_SECURELY, &mm->flags);
smp_wmb();
set_bit(MMF_DUMPABLE, &mm->flags);
break;
}
}
unsigned long old, new;
int __get_dumpable(unsigned long mm_flags)
{
int ret;
if (WARN_ON((unsigned)value > SUID_DUMP_ROOT))
return;
ret = mm_flags & MMF_DUMPABLE_MASK;
return (ret > SUID_DUMP_USER) ? SUID_DUMP_ROOT : ret;
}
/*
* This returns the actual value of the suid_dumpable flag. For things
* that are using this for checking for privilege transitions, it must
* test against SUID_DUMP_USER rather than treating it as a boolean
* value.
*/
int get_dumpable(struct mm_struct *mm)
{
return __get_dumpable(mm->flags);
do {
old = ACCESS_ONCE(mm->flags);
new = (old & ~MMF_DUMPABLE_MASK) | value;
} while (cmpxchg(&mm->flags, old, new) != old);
}
SYSCALL_DEFINE3(execve,

View file

@ -309,43 +309,17 @@ struct fname {
*/
static void free_rb_tree_fname(struct rb_root *root)
{
struct rb_node *n = root->rb_node;
struct rb_node *parent;
struct fname *fname;
struct fname *fname, *next;
while (n) {
/* Do the node's children first */
if (n->rb_left) {
n = n->rb_left;
continue;
}
if (n->rb_right) {
n = n->rb_right;
continue;
}
/*
* The node has no children; free it, and then zero
* out parent's link to it. Finally go to the
* beginning of the loop and try to free the parent
* node.
*/
parent = rb_parent(n);
fname = rb_entry(n, struct fname, rb_hash);
while (fname) {
struct fname * old = fname;
rbtree_postorder_for_each_entry_safe(fname, next, root, rb_hash)
do {
struct fname *old = fname;
fname = fname->next;
kfree (old);
}
if (!parent)
*root = RB_ROOT;
else if (parent->rb_left == n)
parent->rb_left = NULL;
else if (parent->rb_right == n)
parent->rb_right = NULL;
n = parent;
}
}
kfree(old);
} while (fname);
*root = RB_ROOT;
}
static struct dir_private_info *ext3_htree_create_dir_info(struct file *filp,
loff_t pos)

View file

@ -180,37 +180,12 @@ int ext4_setup_system_zone(struct super_block *sb)
/* Called when the filesystem is unmounted */
void ext4_release_system_zone(struct super_block *sb)
{
struct rb_node *n = EXT4_SB(sb)->system_blks.rb_node;
struct rb_node *parent;
struct ext4_system_zone *entry;
struct ext4_system_zone *entry, *n;
while (n) {
/* Do the node's children first */
if (n->rb_left) {
n = n->rb_left;
continue;
}
if (n->rb_right) {
n = n->rb_right;
continue;
}
/*
* The node has no children; free it, and then zero
* out parent's link to it. Finally go to the
* beginning of the loop and try to free the parent
* node.
*/
parent = rb_parent(n);
entry = rb_entry(n, struct ext4_system_zone, node);
rbtree_postorder_for_each_entry_safe(entry, n,
&EXT4_SB(sb)->system_blks, node)
kmem_cache_free(ext4_system_zone_cachep, entry);
if (!parent)
EXT4_SB(sb)->system_blks = RB_ROOT;
else if (parent->rb_left == n)
parent->rb_left = NULL;
else if (parent->rb_right == n)
parent->rb_right = NULL;
n = parent;
}
EXT4_SB(sb)->system_blks = RB_ROOT;
}

View file

@ -353,41 +353,16 @@ struct fname {
*/
static void free_rb_tree_fname(struct rb_root *root)
{
struct rb_node *n = root->rb_node;
struct rb_node *parent;
struct fname *fname;
struct fname *fname, *next;
while (n) {
/* Do the node's children first */
if (n->rb_left) {
n = n->rb_left;
continue;
}
if (n->rb_right) {
n = n->rb_right;
continue;
}
/*
* The node has no children; free it, and then zero
* out parent's link to it. Finally go to the
* beginning of the loop and try to free the parent
* node.
*/
parent = rb_parent(n);
fname = rb_entry(n, struct fname, rb_hash);
rbtree_postorder_for_each_entry_safe(fname, next, root, rb_hash)
while (fname) {
struct fname *old = fname;
fname = fname->next;
kfree(old);
}
if (!parent)
*root = RB_ROOT;
else if (parent->rb_left == n)
parent->rb_left = NULL;
else if (parent->rb_right == n)
parent->rb_right = NULL;
n = parent;
}
*root = RB_ROOT;
}

View file

@ -178,64 +178,6 @@ const struct dentry_operations hfsplus_dentry_operations = {
.d_compare = hfsplus_compare_dentry,
};
static struct dentry *hfsplus_file_lookup(struct inode *dir,
struct dentry *dentry, unsigned int flags)
{
struct hfs_find_data fd;
struct super_block *sb = dir->i_sb;
struct inode *inode = NULL;
struct hfsplus_inode_info *hip;
int err;
if (HFSPLUS_IS_RSRC(dir) || strcmp(dentry->d_name.name, "rsrc"))
goto out;
inode = HFSPLUS_I(dir)->rsrc_inode;
if (inode)
goto out;
inode = new_inode(sb);
if (!inode)
return ERR_PTR(-ENOMEM);
hip = HFSPLUS_I(inode);
inode->i_ino = dir->i_ino;
INIT_LIST_HEAD(&hip->open_dir_list);
mutex_init(&hip->extents_lock);
hip->extent_state = 0;
hip->flags = 0;
hip->userflags = 0;
set_bit(HFSPLUS_I_RSRC, &hip->flags);
err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
if (!err) {
err = hfsplus_find_cat(sb, dir->i_ino, &fd);
if (!err)
err = hfsplus_cat_read_inode(inode, &fd);
hfs_find_exit(&fd);
}
if (err) {
iput(inode);
return ERR_PTR(err);
}
hip->rsrc_inode = dir;
HFSPLUS_I(dir)->rsrc_inode = inode;
igrab(dir);
/*
* __mark_inode_dirty expects inodes to be hashed. Since we don't
* want resource fork inodes in the regular inode space, we make them
* appear hashed, but do not put on any lists. hlist_del()
* will work fine and require no locking.
*/
hlist_add_fake(&inode->i_hash);
mark_inode_dirty(inode);
out:
d_add(dentry, inode);
return NULL;
}
static void hfsplus_get_perms(struct inode *inode,
struct hfsplus_perm *perms, int dir)
{
@ -385,7 +327,6 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
}
static const struct inode_operations hfsplus_file_inode_operations = {
.lookup = hfsplus_file_lookup,
.setattr = hfsplus_setattr,
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,

View file

@ -564,25 +564,10 @@ struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_
they're killed. */
void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
{
struct jffs2_node_frag *frag;
struct jffs2_node_frag *parent;
if (!root->rb_node)
return;
struct jffs2_node_frag *frag, *next;
dbg_fragtree("killing\n");
frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
while(frag) {
if (frag->rb.rb_left) {
frag = frag_left(frag);
continue;
}
if (frag->rb.rb_right) {
frag = frag_right(frag);
continue;
}
rbtree_postorder_for_each_entry_safe(frag, next, root, rb) {
if (frag->node && !(--frag->node->frags)) {
/* Not a hole, and it's the final remaining frag
of this node. Free the node */
@ -591,17 +576,8 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
jffs2_free_full_dnode(frag->node);
}
parent = frag_parent(frag);
if (parent) {
if (frag_left(parent) == frag)
parent->rb.rb_left = NULL;
else
parent->rb.rb_right = NULL;
}
jffs2_free_node_frag(frag);
frag = parent;
cond_resched();
}
}

View file

@ -543,33 +543,13 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c,
static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
{
struct rb_node *this;
struct jffs2_tmp_dnode_info *tn;
struct jffs2_tmp_dnode_info *tn, *next;
this = list->rb_node;
/* Now at bottom of tree */
while (this) {
if (this->rb_left)
this = this->rb_left;
else if (this->rb_right)
this = this->rb_right;
else {
tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
rbtree_postorder_for_each_entry_safe(tn, next, list, rb) {
jffs2_free_full_dnode(tn->fn);
jffs2_free_tmp_dnode_info(tn);
this = rb_parent(this);
if (!this)
break;
if (this->rb_left == &tn->rb)
this->rb_left = NULL;
else if (this->rb_right == &tn->rb)
this->rb_right = NULL;
else BUG();
}
}
*list = RB_ROOT;
}

Some files were not shown because too many files have changed in this diff Show more