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:
Коммит
3aacd625f2
|
@ -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.
|
rescue floppy disk.
|
||||||
|
|
||||||
|
|
||||||
2) Kernel Command Line Parameters
|
2) Parameters
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
|
2a) Kernel Command Line Parameters
|
||||||
|
|
||||||
ramdisk_size=N
|
ramdisk_size=N
|
||||||
==============
|
==============
|
||||||
|
|
||||||
This parameter tells the RAM disk driver to set up RAM disks of N k size. The
|
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
|
rd_nr
|
||||||
default is 1024 (BLOCK_SIZE).
|
=====
|
||||||
|
/dev/ramX devices created.
|
||||||
|
|
||||||
|
max_part
|
||||||
|
========
|
||||||
|
Maximum partition number.
|
||||||
|
|
||||||
|
rd_size
|
||||||
|
=======
|
||||||
|
See ramdisk_size.
|
||||||
|
|
||||||
3) Using "rdev -r"
|
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;
|
return NOTIFY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct notifier_block foobar_cpu_notifer =
|
static struct notifier_block foobar_cpu_notifier =
|
||||||
{
|
{
|
||||||
.notifier_call = foobar_cpu_callback,
|
.notifier_call = foobar_cpu_callback,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>;
|
||||||
|
...
|
||||||
|
};
|
|
@ -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.
|
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||||
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||||
gmt Global Mixed-mode Technology, Inc.
|
gmt Global Mixed-mode Technology, Inc.
|
||||||
|
haoyu Haoyu Microelectronic Co. Ltd.
|
||||||
hisilicon Hisilicon Limited.
|
hisilicon Hisilicon Limited.
|
||||||
hp Hewlett Packard
|
hp Hewlett Packard
|
||||||
ibm International Business Machines (IBM)
|
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
|
~# 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
|
At the syntactical level, a command comprises a sequence of match
|
||||||
specifications, followed by a flags change specification.
|
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' >
|
nullarbor:~ # echo -n 'format "nfsd: READ" +p' >
|
||||||
<debugfs>/dynamic_debug/control
|
<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
|
// enable all messages
|
||||||
nullarbor:~ # echo -n '+p' > <debugfs>/dynamic_debug/control
|
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.
|
- info and examples for the distributed AFS (Andrew File System) fs.
|
||||||
affs.txt
|
affs.txt
|
||||||
- info and mount options for the Amiga Fast File System.
|
- 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
|
automount-support.txt
|
||||||
- information about filesystem automount support.
|
- information about filesystem automount support.
|
||||||
befs.txt
|
befs.txt
|
||||||
- information about the BeOS filesystem for Linux.
|
- information about the BeOS filesystem for Linux.
|
||||||
bfs.txt
|
bfs.txt
|
||||||
- info for the SCO UnixWare Boot Filesystem (BFS).
|
- info for the SCO UnixWare Boot Filesystem (BFS).
|
||||||
|
btrfs.txt
|
||||||
|
- info for the BTRFS filesystem.
|
||||||
|
caching/
|
||||||
|
- directory containing filesystem cache documentation.
|
||||||
ceph.txt
|
ceph.txt
|
||||||
- info for the Ceph Distributed File System
|
- info for the Ceph Distributed File System.
|
||||||
cifs.txt
|
cifs/
|
||||||
- description of the CIFS filesystem.
|
- directory containing CIFS filesystem documentation and example code.
|
||||||
coda.txt
|
coda.txt
|
||||||
- description of the CODA filesystem.
|
- description of the CODA filesystem.
|
||||||
configfs/
|
configfs/
|
||||||
- directory containing configfs documentation and example code.
|
- directory containing configfs documentation and example code.
|
||||||
cramfs.txt
|
cramfs.txt
|
||||||
- info on the cram filesystem for small storage (ROMs etc).
|
- info on the cram filesystem for small storage (ROMs etc).
|
||||||
dentry-locking.txt
|
debugfs.txt
|
||||||
- info on the RCU-based dcache locking model.
|
- info on the debugfs filesystem.
|
||||||
|
devpts.txt
|
||||||
|
- info on the devpts filesystem.
|
||||||
directory-locking
|
directory-locking
|
||||||
- info about the locking scheme used for directory operations.
|
- info about the locking scheme used for directory operations.
|
||||||
dlmfs.txt
|
dlmfs.txt
|
||||||
|
@ -35,7 +43,7 @@ dlmfs.txt
|
||||||
dnotify.txt
|
dnotify.txt
|
||||||
- info about directory notification in Linux.
|
- info about directory notification in Linux.
|
||||||
dnotify_test.c
|
dnotify_test.c
|
||||||
- example program for dnotify
|
- example program for dnotify.
|
||||||
ecryptfs.txt
|
ecryptfs.txt
|
||||||
- docs on eCryptfs: stacked cryptographic filesystem for Linux.
|
- docs on eCryptfs: stacked cryptographic filesystem for Linux.
|
||||||
efivarfs.txt
|
efivarfs.txt
|
||||||
|
@ -48,12 +56,18 @@ ext3.txt
|
||||||
- info, mount options and specifications for the Ext3 filesystem.
|
- info, mount options and specifications for the Ext3 filesystem.
|
||||||
ext4.txt
|
ext4.txt
|
||||||
- info, mount options and specifications for the Ext4 filesystem.
|
- info, mount options and specifications for the Ext4 filesystem.
|
||||||
files.txt
|
|
||||||
- info on file management in the Linux kernel.
|
|
||||||
f2fs.txt
|
f2fs.txt
|
||||||
- info and mount options for the F2FS filesystem.
|
- 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
|
fuse.txt
|
||||||
- info on the Filesystem in User SpacE including mount options.
|
- 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
|
gfs2.txt
|
||||||
- info on the Global File System 2.
|
- info on the Global File System 2.
|
||||||
hfs.txt
|
hfs.txt
|
||||||
|
@ -84,40 +98,58 @@ ntfs.txt
|
||||||
- info and mount options for the NTFS filesystem (Windows NT).
|
- info and mount options for the NTFS filesystem (Windows NT).
|
||||||
ocfs2.txt
|
ocfs2.txt
|
||||||
- info and mount options for the OCFS2 clustered filesystem.
|
- 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
|
porting
|
||||||
- various information on filesystem porting.
|
- various information on filesystem porting.
|
||||||
proc.txt
|
proc.txt
|
||||||
- info on Linux's /proc filesystem.
|
- info on Linux's /proc filesystem.
|
||||||
|
qnx6.txt
|
||||||
|
- info on the QNX6 filesystem.
|
||||||
|
quota.txt
|
||||||
|
- info on Quota subsystem.
|
||||||
ramfs-rootfs-initramfs.txt
|
ramfs-rootfs-initramfs.txt
|
||||||
- info on the 'in memory' filesystems ramfs, rootfs and initramfs.
|
- info on the 'in memory' filesystems ramfs, rootfs and initramfs.
|
||||||
reiser4.txt
|
|
||||||
- info on the Reiser4 filesystem based on dancing tree algorithms.
|
|
||||||
relay.txt
|
relay.txt
|
||||||
- info on relay, for efficient streaming from kernel to user space.
|
- info on relay, for efficient streaming from kernel to user space.
|
||||||
romfs.txt
|
romfs.txt
|
||||||
- description of the ROMFS filesystem.
|
- description of the ROMFS filesystem.
|
||||||
seq_file.txt
|
seq_file.txt
|
||||||
- how to use the seq_file API
|
- how to use the seq_file API.
|
||||||
sharedsubtree.txt
|
sharedsubtree.txt
|
||||||
- a description of shared subtrees for namespaces.
|
- a description of shared subtrees for namespaces.
|
||||||
spufs.txt
|
spufs.txt
|
||||||
- info and mount options for the SPU filesystem used on Cell.
|
- info and mount options for the SPU filesystem used on Cell.
|
||||||
|
squashfs.txt
|
||||||
|
- info on the squashfs filesystem.
|
||||||
sysfs-pci.txt
|
sysfs-pci.txt
|
||||||
- info on accessing PCI device resources through sysfs.
|
- info on accessing PCI device resources through sysfs.
|
||||||
|
sysfs-tagging.txt
|
||||||
|
- info on sysfs tagging to avoid duplicates.
|
||||||
sysfs.txt
|
sysfs.txt
|
||||||
- info on sysfs, a ram-based filesystem for exporting kernel objects.
|
- info on sysfs, a ram-based filesystem for exporting kernel objects.
|
||||||
sysv-fs.txt
|
sysv-fs.txt
|
||||||
- info on the SystemV/V7/Xenix/Coherent filesystem.
|
- info on the SystemV/V7/Xenix/Coherent filesystem.
|
||||||
tmpfs.txt
|
tmpfs.txt
|
||||||
- info on tmpfs, a filesystem that holds all files in virtual memory.
|
- info on tmpfs, a filesystem that holds all files in virtual memory.
|
||||||
|
ubifs.txt
|
||||||
|
- info on the Unsorted Block Images FileSystem.
|
||||||
udf.txt
|
udf.txt
|
||||||
- info and mount options for the UDF filesystem.
|
- info and mount options for the UDF filesystem.
|
||||||
ufs.txt
|
ufs.txt
|
||||||
- info on the ufs filesystem.
|
- info on the ufs filesystem.
|
||||||
vfat.txt
|
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
|
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
|
xfs.txt
|
||||||
- info and mount options for the XFS filesystem.
|
- info and mount options for the XFS filesystem.
|
||||||
xip.txt
|
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
|
block device when blocks are freed. This is useful
|
||||||
for SSD devices and sparse/thinly-provisioned LUNs.
|
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
|
NILFS2 usage
|
||||||
============
|
============
|
||||||
|
|
||||||
|
|
|
@ -108,12 +108,12 @@ static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);
|
||||||
is equivalent to doing:
|
is equivalent to doing:
|
||||||
|
|
||||||
static struct device_attribute dev_attr_foo = {
|
static struct device_attribute dev_attr_foo = {
|
||||||
.attr = {
|
.attr = {
|
||||||
.name = "foo",
|
.name = "foo",
|
||||||
.mode = S_IWUSR | S_IRUGO,
|
.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.
|
debugfs files are removed at module unload time.
|
||||||
|
|
||||||
gpt [EFI] Forces disk with valid GPT signature but
|
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
|
grcan.enable0= [HW] Configuration of physical interface 0. Determines
|
||||||
the "Enable 0" bit of the configuration register.
|
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
|
Valid arguments: on, off
|
||||||
Default: on
|
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
|
kstack=N [X86] Print N words from the kernel stack
|
||||||
in oops dumps.
|
in oops dumps.
|
||||||
|
|
||||||
|
|
|
@ -55,14 +55,21 @@ Struct Resources:
|
||||||
For printing struct resources. The 'R' and 'r' specifiers result in a
|
For printing struct resources. The 'R' and 'r' specifiers result in a
|
||||||
printed resource with ('R') or without ('r') a decoded flags member.
|
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
|
For printing a phys_addr_t type (and its derivatives, such as
|
||||||
resource_size_t) which can vary based on build options, regardless of
|
resource_size_t) which can vary based on build options, regardless of
|
||||||
the width of the CPU data path. Passed by reference.
|
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:
|
Raw buffer as a hex string:
|
||||||
%*ph 00 01 02 ... 3f
|
%*ph 00 01 02 ... 3f
|
||||||
%*phC 00:01:02: ... :3f
|
%*phC 00:01:02: ... :3f
|
||||||
|
|
|
@ -33,6 +33,7 @@ show up in /proc/sys/kernel:
|
||||||
- domainname
|
- domainname
|
||||||
- hostname
|
- hostname
|
||||||
- hotplug
|
- hotplug
|
||||||
|
- kexec_load_disabled
|
||||||
- kptr_restrict
|
- kptr_restrict
|
||||||
- kstack_depth_to_print [ X86 only ]
|
- kstack_depth_to_print [ X86 only ]
|
||||||
- l2cr [ PPC 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:
|
kptr_restrict:
|
||||||
|
|
||||||
This toggle indicates whether restrictions are placed on
|
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
|
in an otherwise modular kernel. This toggle defaults to off
|
||||||
(0), but can be set true (1). Once true, modules can be
|
(0), but can be set true (1). Once true, modules can be
|
||||||
neither loaded nor unloaded, and the toggle cannot be set back
|
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
|
# Static regex used. Specified like this for readability and for use with /o
|
||||||
# (process_pid) (cpus ) ( time ) (tpoint ) (details)
|
# (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_statname = '[-0-9]*\s\((.*)\).*';
|
||||||
my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*';
|
my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*';
|
||||||
|
|
||||||
|
@ -270,8 +270,8 @@ EVENT_PROCESS:
|
||||||
while ($traceevent = <STDIN>) {
|
while ($traceevent = <STDIN>) {
|
||||||
if ($traceevent =~ /$regex_traceevent/o) {
|
if ($traceevent =~ /$regex_traceevent/o) {
|
||||||
$process_pid = $1;
|
$process_pid = $1;
|
||||||
$timestamp = $3;
|
$timestamp = $4;
|
||||||
$tracepoint = $4;
|
$tracepoint = $5;
|
||||||
|
|
||||||
$process_pid =~ /(.*)-([0-9]*)$/;
|
$process_pid =~ /(.*)-([0-9]*)$/;
|
||||||
my $process = $1;
|
my $process = $1;
|
||||||
|
@ -299,7 +299,7 @@ EVENT_PROCESS:
|
||||||
$perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}++;
|
$perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}++;
|
||||||
$perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN} = $timestamp;
|
$perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN} = $timestamp;
|
||||||
|
|
||||||
$details = $5;
|
$details = $6;
|
||||||
if ($details !~ /$regex_direct_begin/o) {
|
if ($details !~ /$regex_direct_begin/o) {
|
||||||
print "WARNING: Failed to parse mm_vmscan_direct_reclaim_begin as expected\n";
|
print "WARNING: Failed to parse mm_vmscan_direct_reclaim_begin as expected\n";
|
||||||
print " $details\n";
|
print " $details\n";
|
||||||
|
@ -322,7 +322,7 @@ EVENT_PROCESS:
|
||||||
$perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] = "$order-$latency";
|
$perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] = "$order-$latency";
|
||||||
}
|
}
|
||||||
} elsif ($tracepoint eq "mm_vmscan_kswapd_wake") {
|
} elsif ($tracepoint eq "mm_vmscan_kswapd_wake") {
|
||||||
$details = $5;
|
$details = $6;
|
||||||
if ($details !~ /$regex_kswapd_wake/o) {
|
if ($details !~ /$regex_kswapd_wake/o) {
|
||||||
print "WARNING: Failed to parse mm_vmscan_kswapd_wake as expected\n";
|
print "WARNING: Failed to parse mm_vmscan_kswapd_wake as expected\n";
|
||||||
print " $details\n";
|
print " $details\n";
|
||||||
|
@ -356,7 +356,7 @@ EVENT_PROCESS:
|
||||||
} elsif ($tracepoint eq "mm_vmscan_wakeup_kswapd") {
|
} elsif ($tracepoint eq "mm_vmscan_wakeup_kswapd") {
|
||||||
$perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}++;
|
$perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}++;
|
||||||
|
|
||||||
$details = $5;
|
$details = $6;
|
||||||
if ($details !~ /$regex_wakeup_kswapd/o) {
|
if ($details !~ /$regex_wakeup_kswapd/o) {
|
||||||
print "WARNING: Failed to parse mm_vmscan_wakeup_kswapd as expected\n";
|
print "WARNING: Failed to parse mm_vmscan_wakeup_kswapd as expected\n";
|
||||||
print " $details\n";
|
print " $details\n";
|
||||||
|
@ -366,7 +366,7 @@ EVENT_PROCESS:
|
||||||
my $order = $3;
|
my $order = $3;
|
||||||
$perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]++;
|
$perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]++;
|
||||||
} elsif ($tracepoint eq "mm_vmscan_lru_isolate") {
|
} elsif ($tracepoint eq "mm_vmscan_lru_isolate") {
|
||||||
$details = $5;
|
$details = $6;
|
||||||
if ($details !~ /$regex_lru_isolate/o) {
|
if ($details !~ /$regex_lru_isolate/o) {
|
||||||
print "WARNING: Failed to parse mm_vmscan_lru_isolate as expected\n";
|
print "WARNING: Failed to parse mm_vmscan_lru_isolate as expected\n";
|
||||||
print " $details\n";
|
print " $details\n";
|
||||||
|
@ -387,7 +387,7 @@ EVENT_PROCESS:
|
||||||
}
|
}
|
||||||
$perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty;
|
$perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty;
|
||||||
} elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") {
|
} elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") {
|
||||||
$details = $5;
|
$details = $6;
|
||||||
if ($details !~ /$regex_lru_shrink_inactive/o) {
|
if ($details !~ /$regex_lru_shrink_inactive/o) {
|
||||||
print "WARNING: Failed to parse mm_vmscan_lru_shrink_inactive as expected\n";
|
print "WARNING: Failed to parse mm_vmscan_lru_shrink_inactive as expected\n";
|
||||||
print " $details\n";
|
print " $details\n";
|
||||||
|
@ -397,7 +397,7 @@ EVENT_PROCESS:
|
||||||
my $nr_reclaimed = $4;
|
my $nr_reclaimed = $4;
|
||||||
$perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED} += $nr_reclaimed;
|
$perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED} += $nr_reclaimed;
|
||||||
} elsif ($tracepoint eq "mm_vmscan_writepage") {
|
} elsif ($tracepoint eq "mm_vmscan_writepage") {
|
||||||
$details = $5;
|
$details = $6;
|
||||||
if ($details !~ /$regex_writepage/o) {
|
if ($details !~ /$regex_writepage/o) {
|
||||||
print "WARNING: Failed to parse mm_vmscan_writepage as expected\n";
|
print "WARNING: Failed to parse mm_vmscan_writepage as expected\n";
|
||||||
print " $details\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: Files and directories with regex patterns.
|
||||||
N: [^a-z]tegra all files whose path contains the word tegra
|
N: [^a-z]tegra all files whose path contains the word tegra
|
||||||
One pattern per line. Multiple N: lines acceptable.
|
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:
|
X: Files and directories that are NOT maintained, same rules as F:
|
||||||
Files exclusions are tested before file matches.
|
Files exclusions are tested before file matches.
|
||||||
Can be useful for excluding a specific subdirectory, for instance:
|
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
|
L: linux-fbdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/video/exynos/exynos_dp*
|
F: drivers/video/exynos/exynos_dp*
|
||||||
F: include/video/exynos_dp*
|
|
||||||
|
|
||||||
EXYNOS MIPI DISPLAY DRIVERS
|
EXYNOS MIPI DISPLAY DRIVERS
|
||||||
M: Inki Dae <inki.dae@samsung.com>
|
M: Inki Dae <inki.dae@samsung.com>
|
||||||
|
@ -3986,6 +3990,12 @@ S: Orphan
|
||||||
F: Documentation/filesystems/hfs.txt
|
F: Documentation/filesystems/hfs.txt
|
||||||
F: fs/hfs/
|
F: fs/hfs/
|
||||||
|
|
||||||
|
HFSPLUS FILESYSTEM
|
||||||
|
L: linux-fsdevel@vger.kernel.org
|
||||||
|
S: Orphan
|
||||||
|
F: Documentation/filesystems/hfsplus.txt
|
||||||
|
F: fs/hfsplus/
|
||||||
|
|
||||||
HGA FRAMEBUFFER DRIVER
|
HGA FRAMEBUFFER DRIVER
|
||||||
M: Ferenc Bakonyi <fero@drama.obuda.kando.hu>
|
M: Ferenc Bakonyi <fero@drama.obuda.kando.hu>
|
||||||
L: linux-nvidia@lists.surfsouth.com
|
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
|
depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
|
||||||
---help---
|
---help---
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
See also the SMP-HOWTO available at
|
See also the SMP-HOWTO available at
|
||||||
|
|
|
@ -128,8 +128,8 @@ config SMP
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
than one CPU, say Y.
|
||||||
|
|
||||||
if SMP
|
if SMP
|
||||||
|
|
||||||
|
|
|
@ -1470,14 +1470,14 @@ config SMP
|
||||||
depends on MMU || ARM_MPU
|
depends on MMU || ARM_MPU
|
||||||
help
|
help
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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
|
you say Y here, the kernel will run on many, but not all,
|
||||||
processor machines. On a single processor machine, the kernel will
|
uniprocessor machines. On a uniprocessor machine, the kernel
|
||||||
run faster if you say N here.
|
will run faster if you say N here.
|
||||||
|
|
||||||
See also <file:Documentation/x86/i386/IO-APIC.txt>,
|
See also <file:Documentation/x86/i386/IO-APIC.txt>,
|
||||||
<file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
|
<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 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 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
|
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
|
||||||
|
|
|
@ -26,45 +26,7 @@
|
||||||
*/
|
*/
|
||||||
#include <asm/mem-layout.h>
|
#include <asm/mem-layout.h>
|
||||||
|
|
||||||
/*
|
#include <asm-generic/fixmap.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define kmap_get_fixmap_pte(vaddr) \
|
#define kmap_get_fixmap_pte(vaddr) \
|
||||||
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), \
|
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), \
|
||||||
|
|
|
@ -104,6 +104,7 @@ config HAVE_SETUP_PER_CPU_AREA
|
||||||
config DMI
|
config DMI
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
select DMI_SCAN_MACHINE_NON_EFI_FALLBACK
|
||||||
|
|
||||||
config EFI
|
config EFI
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
/* Use normal IO mappings for DMI */
|
/* Use normal IO mappings for DMI */
|
||||||
#define dmi_ioremap ioremap
|
#define dmi_early_remap ioremap
|
||||||
#define dmi_iounmap(x,l) iounmap(x)
|
#define dmi_early_unmap(x, l) iounmap(x)
|
||||||
#define dmi_alloc(l) kzalloc(l, GFP_ATOMIC)
|
#define dmi_remap ioremap
|
||||||
|
#define dmi_unmap iounmap
|
||||||
|
#define dmi_alloc(l) kzalloc(l, GFP_ATOMIC)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
#include <asm/fpu.h>
|
#include <asm/fpu.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
|
|
@ -277,13 +277,13 @@ config SMP
|
||||||
bool "Symmetric multi-processing support"
|
bool "Symmetric multi-processing support"
|
||||||
---help---
|
---help---
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
People using multiprocessor machines who say Y here should also say
|
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_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||||
#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK)
|
#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK)
|
||||||
|
|
||||||
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
|
#include <asm-generic/fixmap.h>
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define kmap_get_fixmap_pte(vaddr) \
|
#define kmap_get_fixmap_pte(vaddr) \
|
||||||
pte_offset_kernel( \
|
pte_offset_kernel( \
|
||||||
|
|
|
@ -30,6 +30,7 @@ config MICROBLAZE
|
||||||
select MODULES_USE_ELF_RELA
|
select MODULES_USE_ELF_RELA
|
||||||
select CLONE_BACKWARDS3
|
select CLONE_BACKWARDS3
|
||||||
select CLKSRC_OF
|
select CLKSRC_OF
|
||||||
|
select BUILDTIME_EXTABLE_SORT
|
||||||
|
|
||||||
config SWAP
|
config SWAP
|
||||||
def_bool n
|
def_bool n
|
||||||
|
|
|
@ -58,52 +58,12 @@ enum fixed_addresses {
|
||||||
extern void __set_fixmap(enum fixed_addresses idx,
|
extern void __set_fixmap(enum fixed_addresses idx,
|
||||||
phys_addr_t phys, pgprot_t flags);
|
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_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||||
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
|
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
|
||||||
|
|
||||||
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
|
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_CI
|
||||||
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
|
|
||||||
|
|
||||||
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 __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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2129,13 +2129,13 @@ config SMP
|
||||||
depends on SYS_SUPPORTS_SMP
|
depends on SYS_SUPPORTS_SMP
|
||||||
help
|
help
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
People using multiprocessor machines who say Y here should also say
|
People using multiprocessor machines who say Y here should also say
|
||||||
|
@ -2430,7 +2430,7 @@ source "drivers/pcmcia/Kconfig"
|
||||||
source "drivers/pci/hotplug/Kconfig"
|
source "drivers/pci/hotplug/Kconfig"
|
||||||
|
|
||||||
config RAPIDIO
|
config RAPIDIO
|
||||||
bool "RapidIO support"
|
tristate "RapidIO support"
|
||||||
depends on PCI
|
depends on PCI
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
|
|
|
@ -71,38 +71,7 @@ enum fixed_addresses {
|
||||||
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||||
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
||||||
|
|
||||||
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
|
#include <asm-generic/fixmap.h>
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define kmap_get_fixmap_pte(vaddr) \
|
#define kmap_get_fixmap_pte(vaddr) \
|
||||||
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (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
|
depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050
|
||||||
---help---
|
---help---
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
See also <file:Documentation/x86/i386/IO-APIC.txt>,
|
See also <file:Documentation/x86/i386/IO-APIC.txt>,
|
||||||
|
|
|
@ -229,13 +229,13 @@ config SMP
|
||||||
bool "Symmetric multi-processing support"
|
bool "Symmetric multi-processing support"
|
||||||
---help---
|
---help---
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
See also <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO
|
See also <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO
|
||||||
|
|
|
@ -794,7 +794,7 @@ config HAS_RAPIDIO
|
||||||
default n
|
default n
|
||||||
|
|
||||||
config RAPIDIO
|
config RAPIDIO
|
||||||
bool "RapidIO support"
|
tristate "RapidIO support"
|
||||||
depends on HAS_RAPIDIO || PCI
|
depends on HAS_RAPIDIO || PCI
|
||||||
help
|
help
|
||||||
If you say Y here, the kernel will include drivers and
|
If you say Y here, the kernel will include drivers and
|
||||||
|
@ -802,7 +802,7 @@ config RAPIDIO
|
||||||
|
|
||||||
config FSL_RIO
|
config FSL_RIO
|
||||||
bool "Freescale Embedded SRIO Controller support"
|
bool "Freescale Embedded SRIO Controller support"
|
||||||
depends on RAPIDIO && HAS_RAPIDIO
|
depends on RAPIDIO = y && HAS_RAPIDIO
|
||||||
default "n"
|
default "n"
|
||||||
---help---
|
---help---
|
||||||
Include support for RapidIO controller on Freescale embedded
|
Include support for RapidIO controller on Freescale embedded
|
||||||
|
|
|
@ -58,52 +58,12 @@ enum fixed_addresses {
|
||||||
extern void __set_fixmap (enum fixed_addresses idx,
|
extern void __set_fixmap (enum fixed_addresses idx,
|
||||||
phys_addr_t phys, pgprot_t flags);
|
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_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||||
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
|
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
|
||||||
|
|
||||||
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
|
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_NCG
|
||||||
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
|
|
||||||
|
|
||||||
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 __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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -334,10 +334,10 @@ config SMP
|
||||||
a system with only one CPU, like most personal computers, say N. If
|
a system with only one CPU, like most personal computers, say N. If
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
See also the SMP-HOWTO available at
|
See also the SMP-HOWTO available at
|
||||||
|
|
|
@ -701,13 +701,13 @@ config SMP
|
||||||
depends on SYS_SUPPORTS_SMP
|
depends on SYS_SUPPORTS_SMP
|
||||||
---help---
|
---help---
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
People using multiprocessor machines who say Y here should also say
|
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);
|
unsigned long phys, pgprot_t flags);
|
||||||
extern void __clear_fixmap(enum fixed_addresses idx, 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.
|
* 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_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||||
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
||||||
|
|
||||||
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
|
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_NOCACHE
|
||||||
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
|
|
||||||
|
|
||||||
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
|
#endif
|
||||||
|
|
|
@ -995,29 +995,19 @@ static struct unwinder dwarf_unwinder = {
|
||||||
|
|
||||||
static void dwarf_unwinder_cleanup(void)
|
static void dwarf_unwinder_cleanup(void)
|
||||||
{
|
{
|
||||||
struct rb_node **fde_rb_node = &fde_root.rb_node;
|
struct dwarf_fde *fde, *next_fde;
|
||||||
struct rb_node **cie_rb_node = &cie_root.rb_node;
|
struct dwarf_cie *cie, *next_cie;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deallocate all the memory allocated for the DWARF unwinder.
|
* Deallocate all the memory allocated for the DWARF unwinder.
|
||||||
* Traverse all the FDE/CIE lists and remove and free all the
|
* Traverse all the FDE/CIE lists and remove and free all the
|
||||||
* memory associated with those data structures.
|
* memory associated with those data structures.
|
||||||
*/
|
*/
|
||||||
while (*fde_rb_node) {
|
rbtree_postorder_for_each_entry_safe(fde, next_fde, &fde_root, node)
|
||||||
struct dwarf_fde *fde;
|
|
||||||
|
|
||||||
fde = rb_entry(*fde_rb_node, struct dwarf_fde, node);
|
|
||||||
rb_erase(*fde_rb_node, &fde_root);
|
|
||||||
kfree(fde);
|
kfree(fde);
|
||||||
}
|
|
||||||
|
|
||||||
while (*cie_rb_node) {
|
rbtree_postorder_for_each_entry_safe(cie, next_cie, &cie_root, node)
|
||||||
struct dwarf_cie *cie;
|
|
||||||
|
|
||||||
cie = rb_entry(*cie_rb_node, struct dwarf_cie, node);
|
|
||||||
rb_erase(*cie_rb_node, &cie_root);
|
|
||||||
kfree(cie);
|
kfree(cie);
|
||||||
}
|
|
||||||
|
|
||||||
kmem_cache_destroy(dwarf_reg_cachep);
|
kmem_cache_destroy(dwarf_reg_cachep);
|
||||||
kmem_cache_destroy(dwarf_frame_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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
People using multiprocessor machines who say Y here should also say
|
People using multiprocessor machines who say Y here should also say
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
#include <asm/kmap_types.h>
|
#include <asm/kmap_types.h>
|
||||||
#endif
|
#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
|
* Here we define all the compile-time 'special' virtual
|
||||||
* addresses. The point is to have a constant address at
|
* 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_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_SIZE)
|
||||||
#define FIXADDR_BOOT_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_BOOT_SIZE)
|
#define FIXADDR_BOOT_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_BOOT_SIZE)
|
||||||
|
|
||||||
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 __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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,6 @@ enum fixed_addresses {
|
||||||
extern void __set_fixmap (enum fixed_addresses idx,
|
extern void __set_fixmap (enum fixed_addresses idx,
|
||||||
unsigned long phys, pgprot_t flags);
|
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.
|
* 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_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
|
||||||
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
||||||
|
|
||||||
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
|
#include <asm-generic/fixmap.h>
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -279,13 +279,13 @@ config SMP
|
||||||
bool "Symmetric multi-processing support"
|
bool "Symmetric multi-processing support"
|
||||||
---help---
|
---help---
|
||||||
This enables support for systems with more than one CPU. If you have
|
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
|
a system with only one CPU, say N. If you have a system with more
|
||||||
you have a system with more than one CPU, say Y.
|
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
|
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,
|
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.
|
will run faster if you say N here.
|
||||||
|
|
||||||
Note that if you say Y here and choose architecture "586" or
|
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.
|
# The code disables itself when not needed.
|
||||||
config DMI
|
config DMI
|
||||||
default y
|
default y
|
||||||
|
select DMI_SCAN_MACHINE_NON_EFI_FALLBACK
|
||||||
bool "Enable DMI scanning" if EXPERT
|
bool "Enable DMI scanning" if EXPERT
|
||||||
---help---
|
---help---
|
||||||
Enabled scanning of DMI to identify machine quirks. Say Y
|
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 */
|
/* Use early IO mappings for DMI because it's initialized early */
|
||||||
#define dmi_ioremap early_ioremap
|
#define dmi_early_remap early_ioremap
|
||||||
#define dmi_iounmap early_iounmap
|
#define dmi_early_unmap early_iounmap
|
||||||
|
#define dmi_remap ioremap
|
||||||
|
#define dmi_unmap iounmap
|
||||||
|
|
||||||
#endif /* _ASM_X86_DMI_H */
|
#endif /* _ASM_X86_DMI_H */
|
||||||
|
|
|
@ -175,64 +175,7 @@ static inline void __set_fixmap(enum fixed_addresses idx,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define set_fixmap(idx, phys) \
|
#include <asm-generic/fixmap.h>
|
||||||
__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)
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
#endif /* _ASM_X86_FIXMAP_H */
|
#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)
|
static inline void get_head_page_multiple(struct page *page, int nr)
|
||||||
{
|
{
|
||||||
VM_BUG_ON(page != compound_head(page));
|
VM_BUG_ON_PAGE(page != compound_head(page), page);
|
||||||
VM_BUG_ON(page_count(page) == 0);
|
VM_BUG_ON_PAGE(page_count(page) == 0, page);
|
||||||
atomic_add(nr, &page->_count);
|
atomic_add(nr, &page->_count);
|
||||||
SetPageReferenced(page);
|
SetPageReferenced(page);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr,
|
||||||
head = pte_page(pte);
|
head = pte_page(pte);
|
||||||
page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
|
page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
|
||||||
do {
|
do {
|
||||||
VM_BUG_ON(compound_head(page) != head);
|
VM_BUG_ON_PAGE(compound_head(page) != head, page);
|
||||||
pages[*nr] = page;
|
pages[*nr] = page;
|
||||||
if (PageTail(page))
|
if (PageTail(page))
|
||||||
get_huge_page_tail(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);
|
head = pte_page(pte);
|
||||||
page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
|
page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
|
||||||
do {
|
do {
|
||||||
VM_BUG_ON(compound_head(page) != head);
|
VM_BUG_ON_PAGE(compound_head(page) != head, page);
|
||||||
pages[*nr] = page;
|
pages[*nr] = page;
|
||||||
if (PageTail(page))
|
if (PageTail(page))
|
||||||
get_huge_page_tail(page);
|
get_huge_page_tail(page);
|
||||||
|
|
|
@ -368,7 +368,8 @@ config BLK_DEV_RAM
|
||||||
For details, read <file:Documentation/blockdev/ramdisk.txt>.
|
For details, read <file:Documentation/blockdev/ramdisk.txt>.
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the
|
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
|
Most normal users won't need the RAM disk functionality, and can
|
||||||
thus say N here.
|
thus say N here.
|
||||||
|
|
|
@ -108,6 +108,9 @@ config DMI_SYSFS
|
||||||
under /sys/firmware/dmi when this option is enabled and
|
under /sys/firmware/dmi when this option is enabled and
|
||||||
loaded.
|
loaded.
|
||||||
|
|
||||||
|
config DMI_SCAN_MACHINE_NON_EFI_FALLBACK
|
||||||
|
bool
|
||||||
|
|
||||||
config ISCSI_IBFT_FIND
|
config ISCSI_IBFT_FIND
|
||||||
bool "iSCSI Boot Firmware Table Attributes"
|
bool "iSCSI Boot Firmware Table Attributes"
|
||||||
depends on X86
|
depends on X86
|
||||||
|
|
|
@ -116,7 +116,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
|
||||||
{
|
{
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
|
|
||||||
buf = dmi_ioremap(dmi_base, dmi_len);
|
buf = dmi_early_remap(dmi_base, dmi_len);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
|
||||||
|
|
||||||
add_device_randomness(buf, dmi_len);
|
add_device_randomness(buf, dmi_len);
|
||||||
|
|
||||||
dmi_iounmap(buf, dmi_len);
|
dmi_early_unmap(buf, dmi_len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,18 +527,18 @@ void __init dmi_scan_machine(void)
|
||||||
* needed during early boot. This also means we can
|
* needed during early boot. This also means we can
|
||||||
* iounmap the space when we're done with it.
|
* 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)
|
if (p == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
memcpy_fromio(buf, p, 32);
|
memcpy_fromio(buf, p, 32);
|
||||||
dmi_iounmap(p, 32);
|
dmi_early_unmap(p, 32);
|
||||||
|
|
||||||
if (!dmi_present(buf)) {
|
if (!dmi_present(buf)) {
|
||||||
dmi_available = 1;
|
dmi_available = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (IS_ENABLED(CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK)) {
|
||||||
p = dmi_ioremap(0xF0000, 0x10000);
|
p = dmi_early_remap(0xF0000, 0x10000);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -554,12 +554,12 @@ void __init dmi_scan_machine(void)
|
||||||
memcpy_fromio(buf + 16, q, 16);
|
memcpy_fromio(buf + 16, q, 16);
|
||||||
if (!dmi_present(buf)) {
|
if (!dmi_present(buf)) {
|
||||||
dmi_available = 1;
|
dmi_available = 1;
|
||||||
dmi_iounmap(p, 0x10000);
|
dmi_early_unmap(p, 0x10000);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
memcpy(buf, buf + 16, 16);
|
memcpy(buf, buf + 16, 16);
|
||||||
}
|
}
|
||||||
dmi_iounmap(p, 0x10000);
|
dmi_early_unmap(p, 0x10000);
|
||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
pr_info("DMI not present or invalid.\n");
|
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)
|
if (!dmi_available)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
buf = ioremap(dmi_base, dmi_len);
|
buf = dmi_remap(dmi_base, dmi_len);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
dmi_table(buf, dmi_len, dmi_num, decode, private_data);
|
dmi_table(buf, dmi_len, dmi_num, decode, private_data);
|
||||||
|
|
||||||
iounmap(buf);
|
dmi_unmap(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dmi_walk);
|
EXPORT_SYMBOL_GPL(dmi_walk);
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
#include "intel_bios.h"
|
#include "intel_bios.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||||
static void do_gma_backlight_set(struct drm_device *dev)
|
static void do_gma_backlight_set(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
|
||||||
struct drm_psb_private *dev_priv = dev->dev_private;
|
struct drm_psb_private *dev_priv = dev->dev_private;
|
||||||
backlight_update_status(dev_priv->backlight_device);
|
backlight_update_status(dev_priv->backlight_device);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void gma_backlight_enable(struct drm_device *dev)
|
void gma_backlight_enable(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@ struct omap_mbox_queue {
|
||||||
|
|
||||||
struct omap_mbox {
|
struct omap_mbox {
|
||||||
const char *name;
|
const char *name;
|
||||||
unsigned int irq;
|
int irq;
|
||||||
struct omap_mbox_queue *txq, *rxq;
|
struct omap_mbox_queue *txq, *rxq;
|
||||||
struct omap_mbox_ops *ops;
|
struct omap_mbox_ops *ops;
|
||||||
struct device *dev;
|
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;
|
unsigned int length = sg->length;
|
||||||
u16 sec_cnt = (u16)(length / 512);
|
u16 sec_cnt = (u16)(length / 512);
|
||||||
u8 val, trans_mode, dma_dir;
|
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",
|
dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n",
|
||||||
__func__, tpc, (data_dir == READ) ? "READ" : "WRITE",
|
__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) {
|
if (data_dir == READ) {
|
||||||
dma_dir = DMA_DIR_FROM_CARD;
|
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 {
|
} else {
|
||||||
dma_dir = DMA_DIR_TO_CARD;
|
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_init_cmd(pcr);
|
||||||
|
|
||||||
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
|
||||||
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
|
if (pro_card) {
|
||||||
0xFF, (u8)(sec_cnt >> 8));
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
|
||||||
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L,
|
0xFF, (u8)(sec_cnt >> 8));
|
||||||
0xFF, (u8)sec_cnt);
|
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, MS_TRANS_CFG, 0xFF, cfg);
|
||||||
|
|
||||||
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
|
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);
|
rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
|
||||||
if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT))
|
if (pro_card) {
|
||||||
return -EIO;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -462,8 +472,8 @@ static int rtsx_pci_ms_set_param(struct memstick_host *msh,
|
||||||
clock = 19000000;
|
clock = 19000000;
|
||||||
ssc_depth = RTSX_SSC_DEPTH_500K;
|
ssc_depth = RTSX_SSC_DEPTH_500K;
|
||||||
|
|
||||||
err = rtsx_pci_write_register(pcr, MS_CFG,
|
err = rtsx_pci_write_register(pcr, MS_CFG, 0x58,
|
||||||
0x18, MS_BUS_WIDTH_1);
|
MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
} else if (value == MEMSTICK_PAR4) {
|
} 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) {
|
if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) {
|
||||||
const struct of_device_id *match;
|
const struct of_device_id *match;
|
||||||
match = of_match_node(max8998_dt_match, i2c->dev.of_node);
|
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;
|
return (int)id->driver_data;
|
||||||
|
|
|
@ -170,7 +170,7 @@ static int tps65217_probe(struct i2c_client *client,
|
||||||
"Failed to find matching dt id\n");
|
"Failed to find matching dt id\n");
|
||||||
return -EINVAL;
|
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,
|
status_off = of_property_read_bool(client->dev.of_node,
|
||||||
"ti,pmic-shutdown-controller");
|
"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
|
This driver can also be built as a module. If so, the module
|
||||||
will be called rtc-ds3232.
|
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
|
config RTC_DRV_LP8788
|
||||||
tristate "TI LP8788 RTC driver"
|
tristate "TI LP8788 RTC driver"
|
||||||
depends on MFD_LP8788
|
depends on MFD_LP8788
|
||||||
|
@ -637,7 +648,7 @@ comment "Platform RTC drivers"
|
||||||
|
|
||||||
config RTC_DRV_CMOS
|
config RTC_DRV_CMOS
|
||||||
tristate "PC-style '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
|
default y if X86
|
||||||
help
|
help
|
||||||
Say "yes" here to get direct support for the real time clock
|
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_FM3130) += rtc-fm3130.o
|
||||||
obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.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_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_IMXDI) += rtc-imxdi.o
|
||||||
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
|
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
|
||||||
obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
|
obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/rtc.h>
|
#include <linux/rtc.h>
|
||||||
#include <linux/kdev_t.h>
|
#include <linux/kdev_t.h>
|
||||||
#include <linux/idr.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_device *rtc;
|
||||||
struct rtc_wkalrm alrm;
|
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) {
|
if (id < 0) {
|
||||||
err = id;
|
id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);
|
||||||
goto exit;
|
if (id < 0) {
|
||||||
|
err = id;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
|
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);
|
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);
|
&as3722_rtc_ops, THIS_MODULE);
|
||||||
if (IS_ERR(as3722_rtc->rtc)) {
|
if (IS_ERR(as3722_rtc->rtc)) {
|
||||||
ret = PTR_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);
|
as3722_rtc->alarm_irq = platform_get_irq(pdev, 0);
|
||||||
dev_info(&pdev->dev, "RTC interrupt %d\n", as3722_rtc->alarm_irq);
|
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,
|
as3722_alarm_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME,
|
||||||
"rtc-alarm", as3722_rtc);
|
"rtc-alarm", as3722_rtc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
|
dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
|
||||||
as3722_rtc->alarm_irq, ret);
|
as3722_rtc->alarm_irq, ret);
|
||||||
goto scrub;
|
return ret;
|
||||||
}
|
}
|
||||||
disable_irq(as3722_rtc->alarm_irq);
|
disable_irq(as3722_rtc->alarm_irq);
|
||||||
return 0;
|
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
|
#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 = {
|
static struct platform_driver as3722_rtc_driver = {
|
||||||
.probe = as3722_rtc_probe,
|
.probe = as3722_rtc_probe,
|
||||||
.remove = as3722_rtc_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "as3722-rtc",
|
.name = "as3722-rtc",
|
||||||
.pm = &as3722_rtc_pm_ops,
|
.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;
|
irq_handler_t rtc_cmos_int_handler;
|
||||||
|
|
||||||
if (is_hpet_enabled()) {
|
if (is_hpet_enabled()) {
|
||||||
int err;
|
|
||||||
|
|
||||||
rtc_cmos_int_handler = hpet_rtc_interrupt;
|
rtc_cmos_int_handler = hpet_rtc_interrupt;
|
||||||
err = hpet_register_irq_handler(cmos_interrupt);
|
retval = hpet_register_irq_handler(cmos_interrupt);
|
||||||
if (err != 0) {
|
if (retval) {
|
||||||
dev_warn(dev, "hpet_register_irq_handler "
|
dev_warn(dev, "hpet_register_irq_handler "
|
||||||
" failed in rtc_init().");
|
" failed in rtc_init().");
|
||||||
goto cleanup1;
|
goto cleanup1;
|
||||||
|
@ -1175,7 +1173,7 @@ static struct platform_driver cmos_platform_driver = {
|
||||||
.remove = __exit_p(cmos_platform_remove),
|
.remove = __exit_p(cmos_platform_remove),
|
||||||
.shutdown = cmos_platform_shutdown,
|
.shutdown = cmos_platform_shutdown,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = (char *) driver_name,
|
.name = driver_name,
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
.pm = &cmos_pm_ops,
|
.pm = &cmos_pm_ops,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -787,7 +787,6 @@ static int ds1305_remove(struct spi_device *spi)
|
||||||
cancel_work_sync(&ds1305->work);
|
cancel_work_sync(&ds1305->work);
|
||||||
}
|
}
|
||||||
|
|
||||||
spi_set_drvdata(spi, NULL);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/bcd.h>
|
#include <linux/bcd.h>
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/rtc.h>
|
#include <linux/rtc.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -215,12 +216,19 @@ static int ds1742_rtc_remove(struct platform_device *pdev)
|
||||||
return 0;
|
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 = {
|
static struct platform_driver ds1742_rtc_driver = {
|
||||||
.probe = ds1742_rtc_probe,
|
.probe = ds1742_rtc_probe,
|
||||||
.remove = ds1742_rtc_remove,
|
.remove = ds1742_rtc_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "rtc-ds1742",
|
.name = "rtc-ds1742",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = ds1742_rtc_of_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
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);
|
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;
|
bcd2bin(regs[RTC_YEAR1]) - 1900;
|
||||||
tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1;
|
tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1;
|
||||||
tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f);
|
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) {
|
if (regs[RTC_HOUR] & HOUR_12) {
|
||||||
tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f);
|
tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f);
|
||||||
if (tm->tm_hour == 12)
|
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_YEAR1] = bin2bcd(low);
|
||||||
regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
|
regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
|
||||||
regs[RTC_DATE] = bin2bcd(tm->tm_mday);
|
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_HOUR] = bin2bcd(tm->tm_hour);
|
||||||
regs[RTC_MIN] = bin2bcd(tm->tm_min);
|
regs[RTC_MIN] = bin2bcd(tm->tm_min);
|
||||||
regs[RTC_SEC] = bin2bcd(tm->tm_sec);
|
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);
|
tm_to_regs(&alrm->time, regs);
|
||||||
|
|
||||||
/* Disable alarm while we update the target time */
|
/* 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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -163,8 +163,7 @@ static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (alrm->enabled)
|
if (alrm->enabled)
|
||||||
ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL,
|
ret = regmap_write(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x77);
|
||||||
0x7f, 0x7f);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,11 +391,13 @@ static int mxc_rtc_probe(struct platform_device *pdev)
|
||||||
pdata->clk = devm_clk_get(&pdev->dev, NULL);
|
pdata->clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
if (IS_ERR(pdata->clk)) {
|
if (IS_ERR(pdata->clk)) {
|
||||||
dev_err(&pdev->dev, "unable to get clock!\n");
|
dev_err(&pdev->dev, "unable to get clock!\n");
|
||||||
ret = PTR_ERR(pdata->clk);
|
return PTR_ERR(pdata->clk);
|
||||||
goto exit_free_pdata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_prepare_enable(pdata->clk);
|
ret = clk_prepare_enable(pdata->clk);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
rate = clk_get_rate(pdata->clk);
|
rate = clk_get_rate(pdata->clk);
|
||||||
|
|
||||||
if (rate == 32768)
|
if (rate == 32768)
|
||||||
|
@ -447,8 +449,6 @@ static int mxc_rtc_probe(struct platform_device *pdev)
|
||||||
exit_put_clk:
|
exit_put_clk:
|
||||||
clk_disable_unprepare(pdata->clk);
|
clk_disable_unprepare(pdata->clk);
|
||||||
|
|
||||||
exit_free_pdata:
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,10 +197,7 @@ static int pcf2127_probe(struct i2c_client *client,
|
||||||
pcf2127_driver.driver.name,
|
pcf2127_driver.driver.name,
|
||||||
&pcf2127_rtc_ops, THIS_MODULE);
|
&pcf2127_rtc_ops, THIS_MODULE);
|
||||||
|
|
||||||
if (IS_ERR(pcf2127->rtc))
|
return PTR_ERR_OR_ZERO(pcf2127->rtc);
|
||||||
return PTR_ERR(pcf2127->rtc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_device_id pcf2127_id[] = {
|
static const struct i2c_device_id pcf2127_id[] = {
|
||||||
|
|
|
@ -52,8 +52,45 @@
|
||||||
#define RX8581_CTRL_STOP 0x02 /* STOP bit */
|
#define RX8581_CTRL_STOP 0x02 /* STOP bit */
|
||||||
#define RX8581_CTRL_RESET 0x01 /* RESET 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 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
|
* In the routines that deal directly with the rx8581 hardware, we use
|
||||||
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
|
* 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];
|
unsigned char date[7];
|
||||||
int data, err;
|
int data, err;
|
||||||
|
struct rx8581 *rx8581 = i2c_get_clientdata(client);
|
||||||
|
|
||||||
/* First we ensure that the "update flag" is not set, we read the
|
/* 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
|
* 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,
|
err = i2c_smbus_write_byte_data(client,
|
||||||
RX8581_REG_FLAG, (data & ~RX8581_FLAG_UF));
|
RX8581_REG_FLAG, (data & ~RX8581_FLAG_UF));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
dev_err(&client->dev, "Unable to write device "
|
dev_err(&client->dev, "Unable to write device flags\n");
|
||||||
"flags\n");
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now read time and date */
|
/* 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);
|
7, date);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(&client->dev, "Unable to read date\n");
|
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;
|
int data, err;
|
||||||
unsigned char buf[7];
|
unsigned char buf[7];
|
||||||
|
struct rx8581 *rx8581 = i2c_get_clientdata(client);
|
||||||
|
|
||||||
dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
|
dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
|
||||||
"mday=%d, mon=%d, year=%d, wday=%d\n",
|
"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 */
|
/* 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) {
|
if (err < 0) {
|
||||||
dev_err(&client->dev, "Unable to write to date registers\n");
|
dev_err(&client->dev, "Unable to write to date registers\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -231,22 +269,39 @@ static const struct rtc_class_ops rx8581_rtc_ops = {
|
||||||
static int rx8581_probe(struct i2c_client *client,
|
static int rx8581_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
struct rtc_device *rtc;
|
struct rx8581 *rx8581;
|
||||||
|
|
||||||
dev_dbg(&client->dev, "%s\n", __func__);
|
dev_dbg(&client->dev, "%s\n", __func__);
|
||||||
|
|
||||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)
|
||||||
return -ENODEV;
|
&& !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");
|
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
|
||||||
|
|
||||||
rtc = devm_rtc_device_register(&client->dev, rx8581_driver.driver.name,
|
rx8581->rtc = devm_rtc_device_register(&client->dev,
|
||||||
&rx8581_rtc_ops, THIS_MODULE);
|
rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE);
|
||||||
|
|
||||||
if (IS_ERR(rtc))
|
if (IS_ERR(rx8581->rtc)) {
|
||||||
return PTR_ERR(rtc);
|
dev_err(&client->dev,
|
||||||
|
"unable to register the class device\n");
|
||||||
i2c_set_clientdata(client, rtc);
|
return PTR_ERR(rx8581->rtc);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -639,6 +639,7 @@ static void s5m_rtc_shutdown(struct platform_device *pdev)
|
||||||
s5m_rtc_enable_smpl(info, false);
|
s5m_rtc_enable_smpl(info, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static int s5m_rtc_resume(struct device *dev)
|
static int s5m_rtc_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct s5m_rtc_info *info = dev_get_drvdata(dev);
|
struct s5m_rtc_info *info = dev_get_drvdata(dev);
|
||||||
|
@ -660,6 +661,7 @@ static int s5m_rtc_suspend(struct device *dev)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_PM_SLEEP */
|
||||||
|
|
||||||
static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);
|
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;
|
u8 rd_reg;
|
||||||
|
|
||||||
if (irq <= 0)
|
if (irq <= 0)
|
||||||
goto out1;
|
return ret;
|
||||||
|
|
||||||
/* Initialize the register map */
|
/* Initialize the register map */
|
||||||
if (twl_class_is_4030())
|
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);
|
ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out1;
|
return ret;
|
||||||
|
|
||||||
if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
|
if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
|
||||||
dev_warn(&pdev->dev, "Power up reset detected.\n");
|
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 */
|
/* Clear RTC Power up reset and pending alarm interrupts */
|
||||||
ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
|
ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out1;
|
return ret;
|
||||||
|
|
||||||
if (twl_class_is_6030()) {
|
if (twl_class_is_6030()) {
|
||||||
twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
|
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");
|
dev_info(&pdev->dev, "Enabling TWL-RTC\n");
|
||||||
ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG);
|
ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out1;
|
return ret;
|
||||||
|
|
||||||
/* ensure interrupts are disabled, bootloaders can be strange */
|
/* ensure interrupts are disabled, bootloaders can be strange */
|
||||||
ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG);
|
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 */
|
/* init cached IRQ enable bits */
|
||||||
ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
|
ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out1;
|
return ret;
|
||||||
|
|
||||||
device_init_wakeup(&pdev->dev, 1);
|
device_init_wakeup(&pdev->dev, 1);
|
||||||
|
|
||||||
rtc = rtc_device_register(pdev->name,
|
rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
|
||||||
&pdev->dev, &twl_rtc_ops, THIS_MODULE);
|
&twl_rtc_ops, THIS_MODULE);
|
||||||
if (IS_ERR(rtc)) {
|
if (IS_ERR(rtc)) {
|
||||||
ret = PTR_ERR(rtc);
|
|
||||||
dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
|
dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
|
||||||
PTR_ERR(rtc));
|
PTR_ERR(rtc));
|
||||||
goto out1;
|
return PTR_ERR(rtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
|
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
twl_rtc_interrupt,
|
||||||
dev_name(&rtc->dev), rtc);
|
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
||||||
|
dev_name(&rtc->dev), rtc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&pdev->dev, "IRQ is not free.\n");
|
dev_err(&pdev->dev, "IRQ is not free.\n");
|
||||||
goto out2;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rtc);
|
platform_set_drvdata(pdev, rtc);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out2:
|
|
||||||
rtc_device_unregister(rtc);
|
|
||||||
out1:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -559,9 +554,6 @@ out1:
|
||||||
static int twl_rtc_remove(struct platform_device *pdev)
|
static int twl_rtc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
/* leave rtc running, but disable irqs */
|
/* 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_ALARM_M);
|
||||||
mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
|
mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
|
||||||
if (twl_class_is_6030()) {
|
if (twl_class_is_6030()) {
|
||||||
|
@ -571,10 +563,6 @@ static int twl_rtc_remove(struct platform_device *pdev)
|
||||||
REG_INT_MSK_STS_A);
|
REG_INT_MSK_STS_A);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
free_irq(irq, rtc);
|
|
||||||
|
|
||||||
rtc_device_unregister(rtc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -293,7 +293,7 @@ static int rtc_probe(struct platform_device *pdev)
|
||||||
if (!res)
|
if (!res)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
rtc1_base = ioremap(res->start, resource_size(res));
|
rtc1_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||||
if (!rtc1_base)
|
if (!rtc1_base)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
|
@ -303,13 +303,14 @@ static int rtc_probe(struct platform_device *pdev)
|
||||||
goto err_rtc1_iounmap;
|
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) {
|
if (!rtc2_base) {
|
||||||
retval = -EBUSY;
|
retval = -EBUSY;
|
||||||
goto err_rtc1_iounmap;
|
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)) {
|
if (IS_ERR(rtc)) {
|
||||||
retval = PTR_ERR(rtc);
|
retval = PTR_ERR(rtc);
|
||||||
goto err_iounmap_all;
|
goto err_iounmap_all;
|
||||||
|
@ -330,24 +331,24 @@ static int rtc_probe(struct platform_device *pdev)
|
||||||
aie_irq = platform_get_irq(pdev, 0);
|
aie_irq = platform_get_irq(pdev, 0);
|
||||||
if (aie_irq <= 0) {
|
if (aie_irq <= 0) {
|
||||||
retval = -EBUSY;
|
retval = -EBUSY;
|
||||||
goto err_device_unregister;
|
goto err_iounmap_all;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = request_irq(aie_irq, elapsedtime_interrupt, 0,
|
retval = devm_request_irq(&pdev->dev, aie_irq, elapsedtime_interrupt, 0,
|
||||||
"elapsed_time", pdev);
|
"elapsed_time", pdev);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_device_unregister;
|
goto err_iounmap_all;
|
||||||
|
|
||||||
pie_irq = platform_get_irq(pdev, 1);
|
pie_irq = platform_get_irq(pdev, 1);
|
||||||
if (pie_irq <= 0) {
|
if (pie_irq <= 0) {
|
||||||
retval = -EBUSY;
|
retval = -EBUSY;
|
||||||
goto err_free_irq;
|
goto err_iounmap_all;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = request_irq(pie_irq, rtclong1_interrupt, 0,
|
retval = devm_request_irq(&pdev->dev, pie_irq, rtclong1_interrupt, 0,
|
||||||
"rtclong1", pdev);
|
"rtclong1", pdev);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_free_irq;
|
goto err_iounmap_all;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rtc);
|
platform_set_drvdata(pdev, rtc);
|
||||||
|
|
||||||
|
@ -358,47 +359,20 @@ static int rtc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free_irq:
|
|
||||||
free_irq(aie_irq, pdev);
|
|
||||||
|
|
||||||
err_device_unregister:
|
|
||||||
rtc_device_unregister(rtc);
|
|
||||||
|
|
||||||
err_iounmap_all:
|
err_iounmap_all:
|
||||||
iounmap(rtc2_base);
|
|
||||||
rtc2_base = NULL;
|
rtc2_base = NULL;
|
||||||
|
|
||||||
err_rtc1_iounmap:
|
err_rtc1_iounmap:
|
||||||
iounmap(rtc1_base);
|
|
||||||
rtc1_base = NULL;
|
rtc1_base = NULL;
|
||||||
|
|
||||||
return retval;
|
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 */
|
/* work with hotplug and coldplug */
|
||||||
MODULE_ALIAS("platform:RTC");
|
MODULE_ALIAS("platform:RTC");
|
||||||
|
|
||||||
static struct platform_driver rtc_platform_driver = {
|
static struct platform_driver rtc_platform_driver = {
|
||||||
.probe = rtc_probe,
|
.probe = rtc_probe,
|
||||||
.remove = rtc_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = rtc_name,
|
.name = rtc_name,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
|
|
@ -357,11 +357,13 @@ static int default_lcd_on = 1;
|
||||||
static bool mtrr = true;
|
static bool mtrr = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
||||||
#ifdef CONFIG_PMAC_BACKLIGHT
|
#ifdef CONFIG_PMAC_BACKLIGHT
|
||||||
static int backlight = 1;
|
static int backlight = 1;
|
||||||
#else
|
#else
|
||||||
static int backlight = 0;
|
static int backlight = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* PLL constants */
|
/* PLL constants */
|
||||||
struct aty128_constants {
|
struct aty128_constants {
|
||||||
|
@ -1671,7 +1673,9 @@ static int aty128fb_setup(char *options)
|
||||||
default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
|
default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
|
||||||
continue;
|
continue;
|
||||||
} else if (!strncmp(this_opt, "backlight:", 10)) {
|
} else if (!strncmp(this_opt, "backlight:", 10)) {
|
||||||
|
#ifdef CONFIG_FB_ATY128_BACKLIGHT
|
||||||
backlight = simple_strtoul(this_opt+10, NULL, 0);
|
backlight = simple_strtoul(this_opt+10, NULL, 0);
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_MTRR
|
#ifdef CONFIG_MTRR
|
||||||
|
|
|
@ -110,8 +110,8 @@ static int hp680bl_probe(struct platform_device *pdev)
|
||||||
memset(&props, 0, sizeof(struct backlight_properties));
|
memset(&props, 0, sizeof(struct backlight_properties));
|
||||||
props.type = BACKLIGHT_RAW;
|
props.type = BACKLIGHT_RAW;
|
||||||
props.max_brightness = HP680_MAX_INTENSITY;
|
props.max_brightness = HP680_MAX_INTENSITY;
|
||||||
bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
|
bd = devm_backlight_device_register(&pdev->dev, "hp680-bl", &pdev->dev,
|
||||||
&hp680bl_ops, &props);
|
NULL, &hp680bl_ops, &props);
|
||||||
if (IS_ERR(bd))
|
if (IS_ERR(bd))
|
||||||
return PTR_ERR(bd);
|
return PTR_ERR(bd);
|
||||||
|
|
||||||
|
@ -131,8 +131,6 @@ static int hp680bl_remove(struct platform_device *pdev)
|
||||||
bd->props.power = 0;
|
bd->props.power = 0;
|
||||||
hp680bl_send_intensity(bd);
|
hp680bl_send_intensity(bd);
|
||||||
|
|
||||||
backlight_device_unregister(bd);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,9 +115,10 @@ static int jornada_bl_probe(struct platform_device *pdev)
|
||||||
memset(&props, 0, sizeof(struct backlight_properties));
|
memset(&props, 0, sizeof(struct backlight_properties));
|
||||||
props.type = BACKLIGHT_RAW;
|
props.type = BACKLIGHT_RAW;
|
||||||
props.max_brightness = BL_MAX_BRIGHT;
|
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)) {
|
if (IS_ERR(bd)) {
|
||||||
ret = PTR_ERR(bd);
|
ret = PTR_ERR(bd);
|
||||||
dev_err(&pdev->dev, "failed to register device, err=%x\n", ret);
|
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;
|
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 = {
|
static struct platform_driver jornada_bl_driver = {
|
||||||
.probe = jornada_bl_probe,
|
.probe = jornada_bl_probe,
|
||||||
.remove = jornada_bl_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "jornada_bl",
|
.name = "jornada_bl",
|
||||||
},
|
},
|
||||||
|
|
|
@ -100,7 +100,8 @@ static int jornada_lcd_probe(struct platform_device *pdev)
|
||||||
struct lcd_device *lcd_device;
|
struct lcd_device *lcd_device;
|
||||||
int ret;
|
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)) {
|
if (IS_ERR(lcd_device)) {
|
||||||
ret = PTR_ERR(lcd_device);
|
ret = PTR_ERR(lcd_device);
|
||||||
|
@ -119,18 +120,8 @@ static int jornada_lcd_probe(struct platform_device *pdev)
|
||||||
return 0;
|
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 = {
|
static struct platform_driver jornada_lcd_driver = {
|
||||||
.probe = jornada_lcd_probe,
|
.probe = jornada_lcd_probe,
|
||||||
.remove = jornada_lcd_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "jornada_lcd",
|
.name = "jornada_lcd",
|
||||||
},
|
},
|
||||||
|
|
|
@ -78,7 +78,7 @@ static struct kb3886bl_machinfo *bl_machinfo;
|
||||||
static unsigned long kb3886bl_flags;
|
static unsigned long kb3886bl_flags;
|
||||||
#define KB3886BL_SUSPENDED 0x01
|
#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",
|
.ident = "Sahara Touch-iT",
|
||||||
.matches = {
|
.matches = {
|
||||||
|
|
|
@ -223,8 +223,8 @@ static int l4f00242t03_probe(struct spi_device *spi)
|
||||||
return PTR_ERR(priv->core_reg);
|
return PTR_ERR(priv->core_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->ld = lcd_device_register("l4f00242t03",
|
priv->ld = devm_lcd_device_register(&spi->dev, "l4f00242t03", &spi->dev,
|
||||||
&spi->dev, priv, &l4f_ops);
|
priv, &l4f_ops);
|
||||||
if (IS_ERR(priv->ld))
|
if (IS_ERR(priv->ld))
|
||||||
return PTR_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);
|
struct l4f00242t03_priv *priv = spi_get_drvdata(spi);
|
||||||
|
|
||||||
l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
|
l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN);
|
||||||
lcd_device_unregister(priv->ld);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (addr >= start && addr <= end);
|
return addr >= start && addr <= end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lp8557_bl_off(struct lp855x *lp)
|
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)
|
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)
|
static inline bool is_brightness_ctrl_by_register(enum lp8788_bl_ctrl_mode mode)
|
||||||
{
|
{
|
||||||
return (mode == LP8788_BL_REGISTER_ONLY ||
|
return mode == LP8788_BL_REGISTER_ONLY ||
|
||||||
mode == LP8788_BL_COMB_REGISTER_BASED);
|
mode == LP8788_BL_COMB_REGISTER_BASED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lp8788_backlight_configure(struct lp8788_bl *bl)
|
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));
|
memset(&props, 0, sizeof(struct backlight_properties));
|
||||||
props.type = BACKLIGHT_RAW;
|
props.type = BACKLIGHT_RAW;
|
||||||
props.max_brightness = OMAPBL_MAX_INTENSITY;
|
props.max_brightness = OMAPBL_MAX_INTENSITY;
|
||||||
dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
|
dev = devm_backlight_device_register(&pdev->dev, "omap-bl", &pdev->dev,
|
||||||
&props);
|
bl, &omapbl_ops, &props);
|
||||||
if (IS_ERR(dev))
|
if (IS_ERR(dev))
|
||||||
return PTR_ERR(dev);
|
return PTR_ERR(dev);
|
||||||
|
|
||||||
|
@ -170,20 +170,10 @@ static int omapbl_probe(struct platform_device *pdev)
|
||||||
return 0;
|
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 SIMPLE_DEV_PM_OPS(omapbl_pm_ops, omapbl_suspend, omapbl_resume);
|
||||||
|
|
||||||
static struct platform_driver omapbl_driver = {
|
static struct platform_driver omapbl_driver = {
|
||||||
.probe = omapbl_probe,
|
.probe = omapbl_probe,
|
||||||
.remove = omapbl_remove,
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "omap-bl",
|
.name = "omap-bl",
|
||||||
.pm = &omapbl_pm_ops,
|
.pm = &omapbl_pm_ops,
|
||||||
|
|
|
@ -118,8 +118,9 @@ static int ot200_backlight_probe(struct platform_device *pdev)
|
||||||
props.brightness = 100;
|
props.brightness = 100;
|
||||||
props.type = BACKLIGHT_RAW;
|
props.type = BACKLIGHT_RAW;
|
||||||
|
|
||||||
bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data,
|
bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev),
|
||||||
&ot200_backlight_ops, &props);
|
&pdev->dev, data, &ot200_backlight_ops,
|
||||||
|
&props);
|
||||||
if (IS_ERR(bl)) {
|
if (IS_ERR(bl)) {
|
||||||
dev_err(&pdev->dev, "failed to register backlight\n");
|
dev_err(&pdev->dev, "failed to register backlight\n");
|
||||||
retval = PTR_ERR(bl);
|
retval = PTR_ERR(bl);
|
||||||
|
@ -137,10 +138,6 @@ error_devm_kzalloc:
|
||||||
|
|
||||||
static int ot200_backlight_remove(struct platform_device *pdev)
|
static int ot200_backlight_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct backlight_device *bl = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
backlight_device_unregister(bl);
|
|
||||||
|
|
||||||
/* on module unload set brightness to 100% */
|
/* on module unload set brightness to 100% */
|
||||||
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
|
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
|
||||||
cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
|
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));
|
memset(&props, 0, sizeof(struct backlight_properties));
|
||||||
props.type = BACKLIGHT_RAW;
|
props.type = BACKLIGHT_RAW;
|
||||||
props.max_brightness = 512 - 1;
|
props.max_brightness = 512 - 1;
|
||||||
data->bl = backlight_device_register("tosa-bl", &client->dev, data,
|
data->bl = devm_backlight_device_register(&client->dev, "tosa-bl",
|
||||||
&bl_ops, &props);
|
&client->dev, data, &bl_ops,
|
||||||
|
&props);
|
||||||
if (IS_ERR(data->bl)) {
|
if (IS_ERR(data->bl)) {
|
||||||
ret = PTR_ERR(data->bl);
|
ret = PTR_ERR(data->bl);
|
||||||
goto err_reg;
|
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);
|
struct tosa_bl_data *data = i2c_get_clientdata(client);
|
||||||
|
|
||||||
backlight_device_unregister(data->bl);
|
|
||||||
data->bl = NULL;
|
data->bl = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,8 +206,8 @@ static int tosa_lcd_probe(struct spi_device *spi)
|
||||||
|
|
||||||
tosa_lcd_tg_on(data);
|
tosa_lcd_tg_on(data);
|
||||||
|
|
||||||
data->lcd = lcd_device_register("tosa-lcd", &spi->dev, data,
|
data->lcd = devm_lcd_device_register(&spi->dev, "tosa-lcd", &spi->dev,
|
||||||
&tosa_lcd_ops);
|
data, &tosa_lcd_ops);
|
||||||
|
|
||||||
if (IS_ERR(data->lcd)) {
|
if (IS_ERR(data->lcd)) {
|
||||||
ret = PTR_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);
|
struct tosa_lcd_data *data = spi_get_drvdata(spi);
|
||||||
|
|
||||||
lcd_device_unregister(data->lcd);
|
|
||||||
|
|
||||||
if (data->i2c)
|
if (data->i2c)
|
||||||
i2c_unregister_device(data->i2c);
|
i2c_unregister_device(data->i2c);
|
||||||
|
|
||||||
|
|
|
@ -762,7 +762,8 @@ static int vlynq_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
device_unregister(&dev->dev);
|
device_unregister(&dev->dev);
|
||||||
iounmap(dev->local);
|
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);
|
kfree(dev);
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,31 @@
|
||||||
#include <linux/of_gpio.h>
|
#include <linux/of_gpio.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
#include "../w1.h"
|
#include "../w1.h"
|
||||||
#include "../w1_int.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)
|
static void w1_gpio_write_bit_dir(void *data, u8 bit)
|
||||||
{
|
{
|
||||||
struct w1_gpio_platform_data *pdata = data;
|
struct w1_gpio_platform_data *pdata = data;
|
||||||
|
@ -132,6 +153,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
|
||||||
} else {
|
} else {
|
||||||
gpio_direction_input(pdata->pin);
|
gpio_direction_input(pdata->pin);
|
||||||
master->write_bit = w1_gpio_write_bit_dir;
|
master->write_bit = w1_gpio_write_bit_dir;
|
||||||
|
master->set_pullup = w1_gpio_set_pullup;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w1_add_master_device(master);
|
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");
|
printk(KERN_ERR "w1_add_master_device: invalid function set\n");
|
||||||
return(-EINVAL);
|
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. */
|
/* Lock until the device is added (or not) to w1_masters. */
|
||||||
mutex_lock(&w1_mlock);
|
mutex_lock(&w1_mlock);
|
||||||
|
|
|
@ -104,7 +104,7 @@ struct autofs_sb_info {
|
||||||
u32 magic;
|
u32 magic;
|
||||||
int pipefd;
|
int pipefd;
|
||||||
struct file *pipe;
|
struct file *pipe;
|
||||||
pid_t oz_pgrp;
|
struct pid *oz_pgrp;
|
||||||
int catatonic;
|
int catatonic;
|
||||||
int version;
|
int version;
|
||||||
int sub_version;
|
int sub_version;
|
||||||
|
@ -140,7 +140,7 @@ static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry)
|
||||||
filesystem without "magic".) */
|
filesystem without "magic".) */
|
||||||
|
|
||||||
static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
|
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? */
|
/* Does a dentry have some pending activity? */
|
||||||
|
|
|
@ -346,6 +346,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
|
||||||
{
|
{
|
||||||
int pipefd;
|
int pipefd;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
struct pid *new_pid = NULL;
|
||||||
|
|
||||||
if (param->setpipefd.pipefd == -1)
|
if (param->setpipefd.pipefd == -1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -357,7 +358,17 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
|
||||||
mutex_unlock(&sbi->wq_mutex);
|
mutex_unlock(&sbi->wq_mutex);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
} else {
|
} 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) {
|
if (!pipe) {
|
||||||
err = -EBADF;
|
err = -EBADF;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -367,12 +378,13 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
|
||||||
fput(pipe);
|
fput(pipe);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
sbi->oz_pgrp = task_pgrp_nr(current);
|
swap(sbi->oz_pgrp, new_pid);
|
||||||
sbi->pipefd = pipefd;
|
sbi->pipefd = pipefd;
|
||||||
sbi->pipe = pipe;
|
sbi->pipe = pipe;
|
||||||
sbi->catatonic = 0;
|
sbi->catatonic = 0;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
put_pid(new_pid);
|
||||||
mutex_unlock(&sbi->wq_mutex);
|
mutex_unlock(&sbi->wq_mutex);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,6 +402,20 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
|
||||||
goto next;
|
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))
|
if (simple_empty(dentry))
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,11 @@ void autofs4_kill_sb(struct super_block *sb)
|
||||||
* just call kill_anon_super when we are called from
|
* just call kill_anon_super when we are called from
|
||||||
* deactivate_super.
|
* deactivate_super.
|
||||||
*/
|
*/
|
||||||
if (sbi) /* Free wait queues, close pipe */
|
if (sbi) {
|
||||||
|
/* Free wait queues, close pipe */
|
||||||
autofs4_catatonic_mode(sbi);
|
autofs4_catatonic_mode(sbi);
|
||||||
|
put_pid(sbi->oz_pgrp);
|
||||||
|
}
|
||||||
|
|
||||||
DPRINTK("shutting down");
|
DPRINTK("shutting down");
|
||||||
kill_litter_super(sb);
|
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))
|
if (!gid_eq(root_inode->i_gid, GLOBAL_ROOT_GID))
|
||||||
seq_printf(m, ",gid=%u",
|
seq_printf(m, ",gid=%u",
|
||||||
from_kgid_munged(&init_user_ns, root_inode->i_gid));
|
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, ",timeout=%lu", sbi->exp_timeout/HZ);
|
||||||
seq_printf(m, ",minproto=%d", sbi->min_proto);
|
seq_printf(m, ",minproto=%d", sbi->min_proto);
|
||||||
seq_printf(m, ",maxproto=%d", sbi->max_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,
|
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;
|
char *p;
|
||||||
substring_t args[MAX_OPT_ARGS];
|
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();
|
*uid = current_uid();
|
||||||
*gid = current_gid();
|
*gid = current_gid();
|
||||||
*pgrp = task_pgrp_nr(current);
|
|
||||||
|
|
||||||
*minproto = AUTOFS_MIN_PROTO_VERSION;
|
*minproto = AUTOFS_MIN_PROTO_VERSION;
|
||||||
*maxproto = AUTOFS_MAX_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))
|
if (match_int(args, &option))
|
||||||
return 1;
|
return 1;
|
||||||
*pgrp = option;
|
*pgrp = option;
|
||||||
|
*pgrp_set = true;
|
||||||
break;
|
break;
|
||||||
case Opt_minproto:
|
case Opt_minproto:
|
||||||
if (match_int(args, &option))
|
if (match_int(args, &option))
|
||||||
|
@ -206,10 +210,13 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
|
||||||
int pipefd;
|
int pipefd;
|
||||||
struct autofs_sb_info *sbi;
|
struct autofs_sb_info *sbi;
|
||||||
struct autofs_info *ino;
|
struct autofs_info *ino;
|
||||||
|
int pgrp;
|
||||||
|
bool pgrp_set = false;
|
||||||
|
int ret = -EINVAL;
|
||||||
|
|
||||||
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
|
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
|
||||||
if (!sbi)
|
if (!sbi)
|
||||||
goto fail_unlock;
|
return -ENOMEM;
|
||||||
DPRINTK("starting up, sbi = %p",sbi);
|
DPRINTK("starting up, sbi = %p",sbi);
|
||||||
|
|
||||||
s->s_fs_info = 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->pipe = NULL;
|
||||||
sbi->catatonic = 1;
|
sbi->catatonic = 1;
|
||||||
sbi->exp_timeout = 0;
|
sbi->exp_timeout = 0;
|
||||||
sbi->oz_pgrp = task_pgrp_nr(current);
|
sbi->oz_pgrp = NULL;
|
||||||
sbi->sb = s;
|
sbi->sb = s;
|
||||||
sbi->version = 0;
|
sbi->version = 0;
|
||||||
sbi->sub_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.
|
* Get the root inode and dentry, but defer checking for errors.
|
||||||
*/
|
*/
|
||||||
ino = autofs4_new_ino(sbi);
|
ino = autofs4_new_ino(sbi);
|
||||||
if (!ino)
|
if (!ino) {
|
||||||
|
ret = -ENOMEM;
|
||||||
goto fail_free;
|
goto fail_free;
|
||||||
|
}
|
||||||
root_inode = autofs4_get_inode(s, S_IFDIR | 0755);
|
root_inode = autofs4_get_inode(s, S_IFDIR | 0755);
|
||||||
root = d_make_root(root_inode);
|
root = d_make_root(root_inode);
|
||||||
if (!root)
|
if (!root)
|
||||||
|
@ -255,12 +264,23 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
|
||||||
|
|
||||||
/* Can this call block? */
|
/* Can this call block? */
|
||||||
if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid,
|
if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid,
|
||||||
&sbi->oz_pgrp, &sbi->type, &sbi->min_proto,
|
&pgrp, &pgrp_set, &sbi->type, &sbi->min_proto,
|
||||||
&sbi->max_proto)) {
|
&sbi->max_proto)) {
|
||||||
printk("autofs: called with bogus options\n");
|
printk("autofs: called with bogus options\n");
|
||||||
goto fail_dput;
|
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))
|
if (autofs_type_trigger(sbi->type))
|
||||||
__managed_dentry_set_managed(root);
|
__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->version = sbi->max_proto;
|
||||||
sbi->sub_version = AUTOFS_PROTO_SUBVERSION;
|
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);
|
pipe = fget(pipefd);
|
||||||
|
|
||||||
if (!pipe) {
|
if (!pipe) {
|
||||||
printk("autofs: could not open pipe file descriptor\n");
|
printk("autofs: could not open pipe file descriptor\n");
|
||||||
goto fail_dput;
|
goto fail_dput;
|
||||||
}
|
}
|
||||||
if (autofs_prepare_pipe(pipe) < 0)
|
ret = autofs_prepare_pipe(pipe);
|
||||||
|
if (ret < 0)
|
||||||
goto fail_fput;
|
goto fail_fput;
|
||||||
sbi->pipe = pipe;
|
sbi->pipe = pipe;
|
||||||
sbi->pipefd = pipefd;
|
sbi->pipefd = pipefd;
|
||||||
|
@ -316,10 +337,10 @@ fail_dput:
|
||||||
fail_ino:
|
fail_ino:
|
||||||
kfree(ino);
|
kfree(ino);
|
||||||
fail_free:
|
fail_free:
|
||||||
|
put_pid(sbi->oz_pgrp);
|
||||||
kfree(sbi);
|
kfree(sbi);
|
||||||
s->s_fs_info = NULL;
|
s->s_fs_info = NULL;
|
||||||
fail_unlock:
|
return ret;
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct inode *autofs4_get_inode(struct super_block *sb, umode_t mode)
|
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);
|
dget(dentry);
|
||||||
atomic_inc(&ino->count);
|
atomic_inc(&ino->count);
|
||||||
p_ino = autofs4_dentry_ino(dentry->d_parent);
|
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);
|
atomic_inc(&p_ino->count);
|
||||||
|
|
||||||
dir->i_mtime = CURRENT_TIME;
|
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)) {
|
if (atomic_dec_and_test(&ino->count)) {
|
||||||
p_ino = autofs4_dentry_ino(dentry->d_parent);
|
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);
|
atomic_dec(&p_ino->count);
|
||||||
}
|
}
|
||||||
dput(ino->dentry);
|
dput(ino->dentry);
|
||||||
|
@ -732,7 +732,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t m
|
||||||
dget(dentry);
|
dget(dentry);
|
||||||
atomic_inc(&ino->count);
|
atomic_inc(&ino->count);
|
||||||
p_ino = autofs4_dentry_ino(dentry->d_parent);
|
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);
|
atomic_inc(&p_ino->count);
|
||||||
inc_nlink(dir);
|
inc_nlink(dir);
|
||||||
dir->i_mtime = CURRENT_TIME;
|
dir->i_mtime = CURRENT_TIME;
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
|
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);
|
nd_set_link(nd, dentry->d_inode->i_private);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,11 +347,23 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
|
||||||
struct qstr qstr;
|
struct qstr qstr;
|
||||||
char *name;
|
char *name;
|
||||||
int status, ret, type;
|
int status, ret, type;
|
||||||
|
pid_t pid;
|
||||||
|
pid_t tgid;
|
||||||
|
|
||||||
/* In catatonic mode, we don't wait for nobody */
|
/* In catatonic mode, we don't wait for nobody */
|
||||||
if (sbi->catatonic)
|
if (sbi->catatonic)
|
||||||
return -ENOENT;
|
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) {
|
if (!dentry->d_inode) {
|
||||||
/*
|
/*
|
||||||
* A wait for a negative dentry is invalid for certain
|
* 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->ino = autofs4_get_ino(sbi);
|
||||||
wq->uid = current_uid();
|
wq->uid = current_uid();
|
||||||
wq->gid = current_gid();
|
wq->gid = current_gid();
|
||||||
wq->pid = current->pid;
|
wq->pid = pid;
|
||||||
wq->tgid = current->tgid;
|
wq->tgid = tgid;
|
||||||
wq->status = -EINTR; /* Status return if interrupted */
|
wq->status = -EINTR; /* Status return if interrupted */
|
||||||
wq->wait_ctr = 2;
|
wq->wait_ctr = 2;
|
||||||
|
|
||||||
|
|
|
@ -543,9 +543,6 @@ out:
|
||||||
* libraries. There is no binary dependent code anywhere else.
|
* libraries. There is no binary dependent code anywhere else.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INTERPRETER_NONE 0
|
|
||||||
#define INTERPRETER_ELF 2
|
|
||||||
|
|
||||||
#ifndef STACK_RND_MASK
|
#ifndef STACK_RND_MASK
|
||||||
#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
|
#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
|
|
||||||
#include <trace/events/task.h>
|
#include <trace/events/task.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "coredump.h"
|
|
||||||
|
|
||||||
#include <trace/events/sched.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 <trace/events/task.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "coredump.h"
|
|
||||||
|
|
||||||
#include <trace/events/sched.h>
|
#include <trace/events/sched.h>
|
||||||
|
|
||||||
|
@ -843,7 +842,6 @@ static int exec_mmap(struct mm_struct *mm)
|
||||||
tsk->active_mm = mm;
|
tsk->active_mm = mm;
|
||||||
activate_mm(active_mm, mm);
|
activate_mm(active_mm, mm);
|
||||||
task_unlock(tsk);
|
task_unlock(tsk);
|
||||||
arch_pick_mmap_layout(mm);
|
|
||||||
if (old_mm) {
|
if (old_mm) {
|
||||||
up_read(&old_mm->mmap_sem);
|
up_read(&old_mm->mmap_sem);
|
||||||
BUG_ON(active_mm != old_mm);
|
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 */
|
bprm->mm = NULL; /* We're using it now */
|
||||||
|
|
||||||
set_fs(USER_DS);
|
set_fs(USER_DS);
|
||||||
current->flags &=
|
current->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD |
|
||||||
~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | PF_NOFREEZE);
|
PF_NOFREEZE | PF_NO_SETAFFINITY);
|
||||||
flush_thread();
|
flush_thread();
|
||||||
current->personality &= ~bprm->per_clear;
|
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
|
/* An exec changes our domain. We are no longer part of the thread
|
||||||
group */
|
group */
|
||||||
|
|
||||||
current->self_exec_id++;
|
current->self_exec_id++;
|
||||||
|
|
||||||
flush_signal_handlers(current, 0);
|
flush_signal_handlers(current, 0);
|
||||||
do_close_on_exec(current->files);
|
do_close_on_exec(current->files);
|
||||||
}
|
}
|
||||||
|
@ -1173,6 +1169,10 @@ void free_bprm(struct linux_binprm *bprm)
|
||||||
mutex_unlock(¤t->signal->cred_guard_mutex);
|
mutex_unlock(¤t->signal->cred_guard_mutex);
|
||||||
abort_creds(bprm->cred);
|
abort_creds(bprm->cred);
|
||||||
}
|
}
|
||||||
|
if (bprm->file) {
|
||||||
|
allow_write_access(bprm->file);
|
||||||
|
fput(bprm->file);
|
||||||
|
}
|
||||||
/* If a binfmt changed the interp, free it. */
|
/* If a binfmt changed the interp, free it. */
|
||||||
if (bprm->interp != bprm->filename)
|
if (bprm->interp != bprm->filename)
|
||||||
kfree(bprm->interp);
|
kfree(bprm->interp);
|
||||||
|
@ -1224,11 +1224,10 @@ EXPORT_SYMBOL(install_exec_creds);
|
||||||
* - the caller must hold ->cred_guard_mutex to protect against
|
* - the caller must hold ->cred_guard_mutex to protect against
|
||||||
* PTRACE_ATTACH
|
* 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;
|
struct task_struct *p = current, *t;
|
||||||
unsigned n_fs;
|
unsigned n_fs;
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
if (p->ptrace) {
|
if (p->ptrace) {
|
||||||
if (p->ptrace & PT_PTRACE_CAP)
|
if (p->ptrace & PT_PTRACE_CAP)
|
||||||
|
@ -1244,31 +1243,25 @@ static int check_unsafe_exec(struct linux_binprm *bprm)
|
||||||
if (current->no_new_privs)
|
if (current->no_new_privs)
|
||||||
bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;
|
bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS;
|
||||||
|
|
||||||
|
t = p;
|
||||||
n_fs = 1;
|
n_fs = 1;
|
||||||
spin_lock(&p->fs->lock);
|
spin_lock(&p->fs->lock);
|
||||||
rcu_read_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)
|
if (t->fs == p->fs)
|
||||||
n_fs++;
|
n_fs++;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (p->fs->users > n_fs) {
|
if (p->fs->users > n_fs)
|
||||||
bprm->unsafe |= LSM_UNSAFE_SHARE;
|
bprm->unsafe |= LSM_UNSAFE_SHARE;
|
||||||
} else {
|
else
|
||||||
res = -EAGAIN;
|
p->fs->in_exec = 1;
|
||||||
if (!p->fs->in_exec) {
|
|
||||||
p->fs->in_exec = 1;
|
|
||||||
res = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock(&p->fs->lock);
|
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
|
* Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
|
||||||
*
|
*
|
||||||
* This may be called multiple times for binary chains (scripts for example).
|
* 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);
|
audit_bprm(bprm);
|
||||||
trace_sched_process_exec(current, old_pid, bprm);
|
trace_sched_process_exec(current, old_pid, bprm);
|
||||||
ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
|
ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
|
||||||
current->did_exec = 1;
|
|
||||||
proc_exec_connector(current);
|
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;
|
return ret;
|
||||||
|
@ -1453,7 +1439,6 @@ static int do_execve_common(const char *filename,
|
||||||
struct linux_binprm *bprm;
|
struct linux_binprm *bprm;
|
||||||
struct file *file;
|
struct file *file;
|
||||||
struct files_struct *displaced;
|
struct files_struct *displaced;
|
||||||
bool clear_in_exec;
|
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1485,10 +1470,7 @@ static int do_execve_common(const char *filename,
|
||||||
if (retval)
|
if (retval)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
retval = check_unsafe_exec(bprm);
|
check_unsafe_exec(bprm);
|
||||||
if (retval < 0)
|
|
||||||
goto out_free;
|
|
||||||
clear_in_exec = retval;
|
|
||||||
current->in_execve = 1;
|
current->in_execve = 1;
|
||||||
|
|
||||||
file = open_exec(filename);
|
file = open_exec(filename);
|
||||||
|
@ -1504,7 +1486,7 @@ static int do_execve_common(const char *filename,
|
||||||
|
|
||||||
retval = bprm_mm_init(bprm);
|
retval = bprm_mm_init(bprm);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto out_file;
|
goto out_unmark;
|
||||||
|
|
||||||
bprm->argc = count(argv, MAX_ARG_STRINGS);
|
bprm->argc = count(argv, MAX_ARG_STRINGS);
|
||||||
if ((retval = bprm->argc) < 0)
|
if ((retval = bprm->argc) < 0)
|
||||||
|
@ -1551,15 +1533,8 @@ out:
|
||||||
mmput(bprm->mm);
|
mmput(bprm->mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_file:
|
|
||||||
if (bprm->file) {
|
|
||||||
allow_write_access(bprm->file);
|
|
||||||
fput(bprm->file);
|
|
||||||
}
|
|
||||||
|
|
||||||
out_unmark:
|
out_unmark:
|
||||||
if (clear_in_exec)
|
current->fs->in_exec = 0;
|
||||||
current->fs->in_exec = 0;
|
|
||||||
current->in_execve = 0;
|
current->in_execve = 0;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
|
@ -1609,67 +1584,22 @@ void set_binfmt(struct linux_binfmt *new)
|
||||||
if (new)
|
if (new)
|
||||||
__module_get(new->module);
|
__module_get(new->module);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(set_binfmt);
|
EXPORT_SYMBOL(set_binfmt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set_dumpable converts traditional three-value dumpable to two flags and
|
* set_dumpable stores three-value SUID_DUMP_* into mm->flags.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
void set_dumpable(struct mm_struct *mm, int value)
|
void set_dumpable(struct mm_struct *mm, int value)
|
||||||
{
|
{
|
||||||
switch (value) {
|
unsigned long old, new;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int __get_dumpable(unsigned long mm_flags)
|
if (WARN_ON((unsigned)value > SUID_DUMP_ROOT))
|
||||||
{
|
return;
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mm_flags & MMF_DUMPABLE_MASK;
|
do {
|
||||||
return (ret > SUID_DUMP_USER) ? SUID_DUMP_ROOT : ret;
|
old = ACCESS_ONCE(mm->flags);
|
||||||
}
|
new = (old & ~MMF_DUMPABLE_MASK) | value;
|
||||||
|
} while (cmpxchg(&mm->flags, old, new) != old);
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE3(execve,
|
SYSCALL_DEFINE3(execve,
|
||||||
|
|
|
@ -309,43 +309,17 @@ struct fname {
|
||||||
*/
|
*/
|
||||||
static void free_rb_tree_fname(struct rb_root *root)
|
static void free_rb_tree_fname(struct rb_root *root)
|
||||||
{
|
{
|
||||||
struct rb_node *n = root->rb_node;
|
struct fname *fname, *next;
|
||||||
struct rb_node *parent;
|
|
||||||
struct fname *fname;
|
|
||||||
|
|
||||||
while (n) {
|
rbtree_postorder_for_each_entry_safe(fname, next, root, rb_hash)
|
||||||
/* Do the node's children first */
|
do {
|
||||||
if (n->rb_left) {
|
struct fname *old = fname;
|
||||||
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;
|
|
||||||
fname = fname->next;
|
fname = fname->next;
|
||||||
kfree (old);
|
kfree(old);
|
||||||
}
|
} while (fname);
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
static struct dir_private_info *ext3_htree_create_dir_info(struct file *filp,
|
static struct dir_private_info *ext3_htree_create_dir_info(struct file *filp,
|
||||||
loff_t pos)
|
loff_t pos)
|
||||||
|
|
|
@ -180,37 +180,12 @@ int ext4_setup_system_zone(struct super_block *sb)
|
||||||
/* Called when the filesystem is unmounted */
|
/* Called when the filesystem is unmounted */
|
||||||
void ext4_release_system_zone(struct super_block *sb)
|
void ext4_release_system_zone(struct super_block *sb)
|
||||||
{
|
{
|
||||||
struct rb_node *n = EXT4_SB(sb)->system_blks.rb_node;
|
struct ext4_system_zone *entry, *n;
|
||||||
struct rb_node *parent;
|
|
||||||
struct ext4_system_zone *entry;
|
|
||||||
|
|
||||||
while (n) {
|
rbtree_postorder_for_each_entry_safe(entry, n,
|
||||||
/* Do the node's children first */
|
&EXT4_SB(sb)->system_blks, node)
|
||||||
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);
|
|
||||||
kmem_cache_free(ext4_system_zone_cachep, entry);
|
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;
|
EXT4_SB(sb)->system_blks = RB_ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -353,41 +353,16 @@ struct fname {
|
||||||
*/
|
*/
|
||||||
static void free_rb_tree_fname(struct rb_root *root)
|
static void free_rb_tree_fname(struct rb_root *root)
|
||||||
{
|
{
|
||||||
struct rb_node *n = root->rb_node;
|
struct fname *fname, *next;
|
||||||
struct rb_node *parent;
|
|
||||||
struct fname *fname;
|
|
||||||
|
|
||||||
while (n) {
|
rbtree_postorder_for_each_entry_safe(fname, next, root, rb_hash)
|
||||||
/* 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) {
|
while (fname) {
|
||||||
struct fname *old = fname;
|
struct fname *old = fname;
|
||||||
fname = fname->next;
|
fname = fname->next;
|
||||||
kfree(old);
|
kfree(old);
|
||||||
}
|
}
|
||||||
if (!parent)
|
|
||||||
*root = RB_ROOT;
|
*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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -178,64 +178,6 @@ const struct dentry_operations hfsplus_dentry_operations = {
|
||||||
.d_compare = hfsplus_compare_dentry,
|
.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,
|
static void hfsplus_get_perms(struct inode *inode,
|
||||||
struct hfsplus_perm *perms, int dir)
|
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 = {
|
static const struct inode_operations hfsplus_file_inode_operations = {
|
||||||
.lookup = hfsplus_file_lookup,
|
|
||||||
.setattr = hfsplus_setattr,
|
.setattr = hfsplus_setattr,
|
||||||
.setxattr = generic_setxattr,
|
.setxattr = generic_setxattr,
|
||||||
.getxattr = generic_getxattr,
|
.getxattr = generic_getxattr,
|
||||||
|
|
|
@ -564,25 +564,10 @@ struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_
|
||||||
they're killed. */
|
they're killed. */
|
||||||
void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
|
void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
|
||||||
{
|
{
|
||||||
struct jffs2_node_frag *frag;
|
struct jffs2_node_frag *frag, *next;
|
||||||
struct jffs2_node_frag *parent;
|
|
||||||
|
|
||||||
if (!root->rb_node)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dbg_fragtree("killing\n");
|
dbg_fragtree("killing\n");
|
||||||
|
rbtree_postorder_for_each_entry_safe(frag, next, root, rb) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frag->node && !(--frag->node->frags)) {
|
if (frag->node && !(--frag->node->frags)) {
|
||||||
/* Not a hole, and it's the final remaining frag
|
/* Not a hole, and it's the final remaining frag
|
||||||
of this node. Free the node */
|
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);
|
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);
|
jffs2_free_node_frag(frag);
|
||||||
frag = parent;
|
|
||||||
|
|
||||||
cond_resched();
|
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)
|
static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
|
||||||
{
|
{
|
||||||
struct rb_node *this;
|
struct jffs2_tmp_dnode_info *tn, *next;
|
||||||
struct jffs2_tmp_dnode_info *tn;
|
|
||||||
|
|
||||||
this = list->rb_node;
|
rbtree_postorder_for_each_entry_safe(tn, next, list, rb) {
|
||||||
|
|
||||||
/* 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);
|
|
||||||
jffs2_free_full_dnode(tn->fn);
|
jffs2_free_full_dnode(tn->fn);
|
||||||
jffs2_free_tmp_dnode_info(tn);
|
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;
|
*list = RB_ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче