mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-18 18:43:59 +08:00
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:
commit
3aacd625f2
14
Documentation/ABI/testing/sysfs-kernel-vmcoreinfo
Normal file
14
Documentation/ABI/testing/sysfs-kernel-vmcoreinfo
Normal 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.
|
@ -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"
|
||||
------------------
|
||||
|
@ -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,
|
||||
};
|
||||
|
27
Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt
Normal file
27
Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt
Normal 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>;
|
||||
...
|
||||
};
|
12
Documentation/devicetree/bindings/rtc/maxim,ds1742.txt
Normal file
12
Documentation/devicetree/bindings/rtc/maxim,ds1742.txt
Normal 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>;
|
||||
};
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
============
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
==============================================================
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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.
|
12
MAINTAINERS
12
MAINTAINERS
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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), \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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( \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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>,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -787,7 +787,6 @@ static int ds1305_remove(struct spi_device *spi)
|
||||
cancel_work_sync(&ds1305->work);
|
||||
}
|
||||
|
||||
spi_set_drvdata(spi, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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
606
drivers/rtc/rtc-hym8563.c
Normal 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");
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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[] = {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 @@ out1:
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
},
|
||||
|
@ -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",
|
||||
},
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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 @@ error_devm_kzalloc:
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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? */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 @@ fail_dput:
|
||||
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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -543,9 +543,6 @@ out:
|
||||
* 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
|
||||
|
@ -40,7 +40,6 @@
|
||||
|
||||
#include <trace/events/task.h>
|
||||
#include "internal.h"
|
||||
#include "coredump.h"
|
||||
|
||||
#include <trace/events/sched.h>
|
||||
|
||||
|
@ -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
120
fs/exec.c
@ -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(¤t->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 @@ out:
|
||||
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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user