Merge branch 'akpm' (patches from Andrew)

Merge third patchbomb from Andrew Morton:

 - various misc things

 - a couple of lib/ optimisations

 - provide DIV_ROUND_CLOSEST_ULL()

 - checkpatch updates

 - rtc tree

 - befs, nilfs2, hfs, hfsplus, fatfs, adfs, affs, bfs

 - ptrace fixes

 - fork() fixes

 - seccomp cleanups

 - more mmap_sem hold time reductions from Davidlohr

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (138 commits)
  proc: show locks in /proc/pid/fdinfo/X
  docs: add missing and new /proc/PID/status file entries, fix typos
  drivers/rtc/rtc-at91rm9200.c: make IO endian agnostic
  Documentation/spi/spidev_test.c: fix warning
  drivers/rtc/rtc-s5m.c: allow usage on device type different than main MFD type
  .gitignore: ignore *.tar
  MAINTAINERS: add Mediatek SoC mailing list
  tomoyo: reduce mmap_sem hold for mm->exe_file
  powerpc/oprofile: reduce mmap_sem hold for exe_file
  oprofile: reduce mmap_sem hold for mm->exe_file
  mips: ip32: add platform data hooks to use DS1685 driver
  lib/Kconfig: fix up HAVE_ARCH_BITREVERSE help text
  x86: switch to using asm-generic for seccomp.h
  sparc: switch to using asm-generic for seccomp.h
  powerpc: switch to using asm-generic for seccomp.h
  parisc: switch to using asm-generic for seccomp.h
  mips: switch to using asm-generic for seccomp.h
  microblaze: use asm-generic for seccomp.h
  arm: use asm-generic for seccomp.h
  seccomp: allow COMPAT sigreturn overrides
  ...
This commit is contained in:
Linus Torvalds 2015-04-17 09:04:38 -04:00
commit 54e514b91b
158 changed files with 2194 additions and 1555 deletions

1
.gitignore vendored
View File

@ -24,6 +24,7 @@
*.order
*.elf
*.bin
*.tar
*.gz
*.bz2
*.lzma

View File

@ -659,6 +659,19 @@ macros using parameters.
#define CONSTANT 0x4000
#define CONSTEXP (CONSTANT | 3)
5) namespace collisions when defining local variables in macros resembling
functions:
#define FOO(x) \
({ \
typeof(x) ret; \
ret = calc_ret(x); \
(ret); \
)}
ret is a common name for a local variable - __foo_ret is less likely
to collide with an existing variable.
The cpp manual deals with macros exhaustively. The gcc internals manual also
covers RTL which is used frequently with assembly language in the kernel.

View File

@ -614,8 +614,8 @@ The canonical patch message body contains the following:
- An empty line.
- The body of the explanation, which will be copied to the
permanent changelog to describe this patch.
- The body of the explanation, line wrapped at 75 columns, which will
be copied to the permanent changelog to describe this patch.
- The "Signed-off-by:" lines, described above, which will
also go in the changelog.

View File

@ -0,0 +1,17 @@
Conexant Digicolor Real Time Clock controller
This binding currently supports the CX92755 SoC.
Required properties:
- compatible: should be "cnxt,cx92755-rtc"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: rtc alarm interrupt
Example:
rtc@f0000c30 {
compatible = "cnxt,cx92755-rtc";
reg = <0xf0000c30 0x18>;
interrupts = <25>;
};

View File

@ -7,6 +7,11 @@ Required properties:
region.
- interrupts: rtc alarm interrupt
Optional properties:
- stmp,crystal-freq: override crystal frequency as determined from fuse bits.
Only <32000> and <32768> are possible for the hardware. Use <0> for
"no crystal".
Example:
rtc@80056000 {

View File

@ -200,12 +200,12 @@ contains details information about the process itself. Its fields are
explained in Table 1-4.
(for SMP CONFIG users)
For making accounting scalable, RSS related information are handled in
asynchronous manner and the vaule may not be very precise. To see a precise
For making accounting scalable, RSS related information are handled in an
asynchronous manner and the value may not be very precise. To see a precise
snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table.
It's slow but very precise.
Table 1-2: Contents of the status files (as of 2.6.30-rc7)
Table 1-2: Contents of the status files (as of 3.20.0)
..............................................................................
Field Content
Name filename of the executable
@ -213,6 +213,7 @@ Table 1-2: Contents of the status files (as of 2.6.30-rc7)
in an uninterruptible wait, Z is zombie,
T is traced or stopped)
Tgid thread group ID
Ngid NUMA group ID (0 if none)
Pid process id
PPid process id of the parent process
TracerPid PID of process tracing this process (0 if not)
@ -220,6 +221,10 @@ Table 1-2: Contents of the status files (as of 2.6.30-rc7)
Gid Real, effective, saved set, and file system GIDs
FDSize number of file descriptor slots currently allocated
Groups supplementary group list
NStgid descendant namespace thread group ID hierarchy
NSpid descendant namespace process ID hierarchy
NSpgid descendant namespace process group ID hierarchy
NSsid descendant namespace session ID hierarchy
VmPeak peak virtual memory size
VmSize total program size
VmLck locked memory size
@ -1704,6 +1709,10 @@ A typical output is
flags: 0100002
mnt_id: 19
All locks associated with a file descriptor are shown in its fdinfo too.
lock: 1: FLOCK ADVISORY WRITE 359 00:13:11691 0 EOF
The files such as eventfd, fsnotify, signalfd, epoll among the regular pos/flags
pair provide additional information particular to the objects they represent.

View File

@ -80,7 +80,7 @@ static void hex_dump(const void *src, size_t length, size_t line_size, char *pre
* Unescape - process hexadecimal escape character
* converts shell input "\x23" -> 0x23
*/
int unespcape(char *_dst, char *_src, size_t len)
static int unescape(char *_dst, char *_src, size_t len)
{
int ret = 0;
char *src = _src;
@ -304,7 +304,7 @@ int main(int argc, char *argv[])
size = strlen(input_tx+1);
tx = malloc(size);
rx = malloc(size);
size = unespcape((char *)tx, input_tx, size);
size = unescape((char *)tx, input_tx, size);
transfer(fd, tx, rx, size);
free(rx);
free(tx);

View File

@ -872,6 +872,27 @@ can be ORed together:
==============================================================
threads-max
This value controls the maximum number of threads that can be created
using fork().
During initialization the kernel sets this value such that even if the
maximum number of threads is created, the thread structures occupy only
a part (1/8th) of the available RAM pages.
The minimum value that can be written to threads-max is 20.
The maximum value that can be written to threads-max is given by the
constant FUTEX_TID_MASK (0x3fffffff).
If a value outside of this range is written to threads-max an error
EINVAL occurs.
The value written is checked against the available RAM pages. If the
thread structures would occupy too much (more than 1/8th) of the
available RAM pages threads-max is reduced accordingly.
==============================================================
unknown_nmi_panic:
The value in this file affects behavior of handling NMI. When the

View File

@ -1215,6 +1215,7 @@ F: arch/arm/mach-orion5x/ts78xx-*
ARM/Mediatek SoC support
M: Matthias Brugger <matthias.bgg@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/boot/dts/mt6*
F: arch/arm/boot/dts/mt8*
@ -8183,6 +8184,7 @@ X: kernel/torture.c
REAL TIME CLOCK (RTC) SUBSYSTEM
M: Alessandro Zummo <a.zummo@towertech.it>
M: Alexandre Belloni <alexandre.belloni@free-electrons.com>
L: rtc-linux@googlegroups.com
Q: http://patchwork.ozlabs.org/project/rtc-linux/list/
S: Maintained

View File

@ -44,6 +44,7 @@ struct task_struct;
extern unsigned long thread_saved_pc(struct task_struct *);
/* Do necessary setup to start up a newly executed thread. */
struct pt_regs;
extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
/* Free all resources held by a thread. */

View File

@ -52,7 +52,7 @@ static void show_callee_regs(struct callee_regs *cregs)
print_reg_file(&(cregs->r13), 13);
}
void print_task_path_n_nm(struct task_struct *tsk, char *buf)
static void print_task_path_n_nm(struct task_struct *tsk, char *buf)
{
struct path path;
char *path_nm = NULL;
@ -77,7 +77,6 @@ void print_task_path_n_nm(struct task_struct *tsk, char *buf)
done:
pr_info("Path: %s\n", path_nm);
}
EXPORT_SYMBOL(print_task_path_n_nm);
static void show_faulting_vma(unsigned long address, char *buf)
{

View File

@ -21,6 +21,7 @@ generic-y += preempt.h
generic-y += resource.h
generic-y += rwsem.h
generic-y += scatterlist.h
generic-y += seccomp.h
generic-y += sections.h
generic-y += segment.h
generic-y += sembuf.h

View File

@ -1,11 +0,0 @@
#ifndef _ASM_ARM_SECCOMP_H
#define _ASM_ARM_SECCOMP_H
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#endif /* _ASM_ARM_SECCOMP_H */

View File

@ -3,14 +3,8 @@
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_sigreturn
#define __NR_seccomp_read_32 __NR_read
#define __NR_seccomp_write_32 __NR_write
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
#include <asm-generic/seccomp.h>
#endif /* _ASM_MICROBLAZE_SECCOMP_H */

View File

@ -105,7 +105,8 @@ CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
# CONFIG_RTC_INTF_SYSFS is not set
# CONFIG_RTC_INTF_PROC is not set
CONFIG_RTC_DRV_CMOS=y
CONFIG_RTC_DRV_DS1685_FAMILY=y
CONFIG_RTC_DRV_DS1685=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y

View File

@ -1,36 +0,0 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1998, 2001, 03 by Ralf Baechle
* Copyright (C) 2000 Harald Koerfgen
*
* RTC routines for IP32 style attached Dallas chip.
*/
#ifndef __ASM_MACH_IP32_MC146818RTC_H
#define __ASM_MACH_IP32_MC146818RTC_H
#include <asm/ip32/mace.h>
#define RTC_PORT(x) (0x70 + (x))
static unsigned char CMOS_READ(unsigned long addr)
{
return mace->isa.rtc[addr << 8];
}
static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
{
mace->isa.rtc[addr << 8] = data;
}
/*
* FIXME: Do it right. For now just assume that no one lives in 20th century
* and no O2 user in 22th century ;-)
*/
#define mc146818_decode_year(year) ((year) + 2000)
#define RTC_ALWAYS_BCD 0
#endif /* __ASM_MACH_IP32_MC146818RTC_H */

View File

@ -2,11 +2,6 @@
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
/*
* Kludge alert:
*
@ -29,4 +24,6 @@
#endif /* CONFIG_MIPS32_O32 */
#include <asm-generic/seccomp.h>
#endif /* __ASM_SECCOMP_H */

View File

@ -9,10 +9,13 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/rtc/ds1685.h>
#include <asm/ip32/mace.h>
#include <asm/ip32/ip32_ints.h>
extern void ip32_prepare_poweroff(void);
#define MACEISA_SERIAL1_OFFS offsetof(struct sgi_mace, isa.serial1)
#define MACEISA_SERIAL2_OFFS offsetof(struct sgi_mace, isa.serial2)
@ -90,18 +93,47 @@ static __init int sgio2btns_devinit(void)
device_initcall(sgio2btns_devinit);
static struct resource sgio2_cmos_rsrc[] = {
#define MACE_RTC_RES_START (MACE_BASE + offsetof(struct sgi_mace, isa.rtc))
#define MACE_RTC_RES_END (MACE_RTC_RES_START + 32767)
static struct resource ip32_rtc_resources[] = {
{
.start = 0x70,
.end = 0x71,
.flags = IORESOURCE_IO
.start = MACEISA_RTC_IRQ,
.end = MACEISA_RTC_IRQ,
.flags = IORESOURCE_IRQ
}, {
.start = MACE_RTC_RES_START,
.end = MACE_RTC_RES_END,
.flags = IORESOURCE_MEM,
}
};
static __init int sgio2_cmos_devinit(void)
/* RTC registers on IP32 are each padded by 256 bytes (0x100). */
static struct ds1685_rtc_platform_data
ip32_rtc_platform_data[] = {
{
.regstep = 0x100,
.bcd_mode = true,
.no_irq = false,
.uie_unsupported = false,
.alloc_io_resources = true,
.plat_prepare_poweroff = ip32_prepare_poweroff,
},
};
struct platform_device ip32_rtc_device = {
.name = "rtc-ds1685",
.id = -1,
.dev = {
.platform_data = ip32_rtc_platform_data,
},
.num_resources = ARRAY_SIZE(ip32_rtc_resources),
.resource = ip32_rtc_resources,
};
+static int __init sgio2_rtc_devinit(void)
{
return IS_ERR(platform_device_register_simple("rtc_cmos", -1,
sgio2_cmos_rsrc, 1));
return platform_device_register(&ip32_rtc_device);
}
device_initcall(sgio2_cmos_devinit);

View File

@ -11,10 +11,11 @@
#include <linux/compiler.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/notifier.h>
#include <linux/delay.h>
#include <linux/ds17287rtc.h>
#include <linux/rtc/ds1685.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
@ -33,53 +34,40 @@
#define POWERDOWN_FREQ (HZ / 4)
#define PANIC_FREQ (HZ / 8)
static struct timer_list power_timer, blink_timer, debounce_timer;
static int has_panicked, shuting_down;
extern struct platform_device ip32_rtc_device;
static void ip32_machine_restart(char *command) __noreturn;
static void ip32_machine_halt(void) __noreturn;
static void ip32_machine_power_off(void) __noreturn;
static struct timer_list power_timer, blink_timer;
static int has_panicked, shutting_down;
static __noreturn void ip32_poweroff(void *data)
{
void (*poweroff_func)(struct platform_device *) =
symbol_get(ds1685_rtc_poweroff);
#ifdef CONFIG_MODULES
/* If the first __symbol_get failed, our module wasn't loaded. */
if (!poweroff_func) {
request_module("rtc-ds1685");
poweroff_func = symbol_get(ds1685_rtc_poweroff);
}
#endif
if (!poweroff_func)
pr_emerg("RTC not available for power-off. Spinning forever ...\n");
else {
(*poweroff_func)((struct platform_device *)data);
symbol_put(ds1685_rtc_poweroff);
}
unreachable();
}
static void ip32_machine_restart(char *cmd) __noreturn;
static void ip32_machine_restart(char *cmd)
{
msleep(20);
crime->control = CRIME_CONTROL_HARD_RESET;
while (1);
}
static inline void ip32_machine_halt(void)
{
ip32_machine_power_off();
}
static void ip32_machine_power_off(void)
{
unsigned char reg_a, xctrl_a, xctrl_b;
disable_irq(MACEISA_RTC_IRQ);
reg_a = CMOS_READ(RTC_REG_A);
/* setup for kickstart & wake-up (DS12287 Ref. Man. p. 19) */
reg_a &= ~DS_REGA_DV2;
reg_a |= DS_REGA_DV1;
CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
wbflush();
xctrl_b = CMOS_READ(DS_B1_XCTRL4B)
| DS_XCTRL4B_ABE | DS_XCTRL4B_KFE;
CMOS_WRITE(xctrl_b, DS_B1_XCTRL4B);
xctrl_a = CMOS_READ(DS_B1_XCTRL4A) & ~DS_XCTRL4A_IFS;
CMOS_WRITE(xctrl_a, DS_B1_XCTRL4A);
wbflush();
/* adios amigos... */
CMOS_WRITE(xctrl_a | DS_XCTRL4A_PAB, DS_B1_XCTRL4A);
CMOS_WRITE(reg_a, RTC_REG_A);
wbflush();
while (1);
}
static void power_timeout(unsigned long data)
{
ip32_machine_power_off();
unreachable();
}
static void blink_timeout(unsigned long data)
@ -89,44 +77,27 @@ static void blink_timeout(unsigned long data)
mod_timer(&blink_timer, jiffies + data);
}
static void debounce(unsigned long data)
static void ip32_machine_halt(void)
{
unsigned char reg_a, reg_c, xctrl_a;
reg_c = CMOS_READ(RTC_INTR_FLAGS);
reg_a = CMOS_READ(RTC_REG_A);
CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
wbflush();
xctrl_a = CMOS_READ(DS_B1_XCTRL4A);
if ((xctrl_a & DS_XCTRL4A_IFS) || (reg_c & RTC_IRQF )) {
/* Interrupt still being sent. */
debounce_timer.expires = jiffies + 50;
add_timer(&debounce_timer);
/* clear interrupt source */
CMOS_WRITE(xctrl_a & ~DS_XCTRL4A_IFS, DS_B1_XCTRL4A);
CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
return;
}
CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
if (has_panicked)
ip32_machine_restart(NULL);
enable_irq(MACEISA_RTC_IRQ);
ip32_poweroff(&ip32_rtc_device);
}
static inline void ip32_power_button(void)
static void power_timeout(unsigned long data)
{
ip32_poweroff(&ip32_rtc_device);
}
void ip32_prepare_poweroff(void)
{
if (has_panicked)
return;
if (shuting_down || kill_cad_pid(SIGINT, 1)) {
if (shutting_down || kill_cad_pid(SIGINT, 1)) {
/* No init process or button pressed twice. */
ip32_machine_power_off();
ip32_poweroff(&ip32_rtc_device);
}
shuting_down = 1;
shutting_down = 1;
blink_timer.data = POWERDOWN_FREQ;
blink_timeout(POWERDOWN_FREQ);
@ -136,27 +107,6 @@ static inline void ip32_power_button(void)
add_timer(&power_timer);
}
static irqreturn_t ip32_rtc_int(int irq, void *dev_id)
{
unsigned char reg_c;
reg_c = CMOS_READ(RTC_INTR_FLAGS);
if (!(reg_c & RTC_IRQF)) {
printk(KERN_WARNING
"%s: RTC IRQ without RTC_IRQF\n", __func__);
}
/* Wait until interrupt goes away */
disable_irq_nosync(MACEISA_RTC_IRQ);
init_timer(&debounce_timer);
debounce_timer.function = debounce;
debounce_timer.expires = jiffies + 50;
add_timer(&debounce_timer);
printk(KERN_DEBUG "Power button pressed\n");
ip32_power_button();
return IRQ_HANDLED;
}
static int panic_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
@ -190,15 +140,12 @@ static __init int ip32_reboot_setup(void)
_machine_restart = ip32_machine_restart;
_machine_halt = ip32_machine_halt;
pm_power_off = ip32_machine_power_off;
pm_power_off = ip32_machine_halt;
init_timer(&blink_timer);
blink_timer.function = blink_timeout;
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
if (request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL))
panic("Can't allocate MACEISA RTC IRQ");
return 0;
}

View File

@ -20,6 +20,7 @@ generic-y += param.h
generic-y += percpu.h
generic-y += poll.h
generic-y += preempt.h
generic-y += seccomp.h
generic-y += segment.h
generic-y += topology.h
generic-y += trace_clock.h

View File

@ -1,16 +0,0 @@
#ifndef _ASM_PARISC_SECCOMP_H
#define _ASM_PARISC_SECCOMP_H
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#define __NR_seccomp_read_32 __NR_read
#define __NR_seccomp_write_32 __NR_write
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_rt_sigreturn
#endif /* _ASM_PARISC_SECCOMP_H */

View File

@ -0,0 +1,10 @@
#ifndef _ASM_POWERPC_SECCOMP_H
#define _ASM_POWERPC_SECCOMP_H
#include <linux/unistd.h>
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
#include <asm-generic/seccomp.h>
#endif /* _ASM_POWERPC_SECCOMP_H */

View File

@ -25,7 +25,6 @@ header-y += posix_types.h
header-y += ps3fb.h
header-y += ptrace.h
header-y += resource.h
header-y += seccomp.h
header-y += sembuf.h
header-y += setup.h
header-y += shmbuf.h

View File

@ -1,16 +0,0 @@
#ifndef _ASM_POWERPC_SECCOMP_H
#define _ASM_POWERPC_SECCOMP_H
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#define __NR_seccomp_read_32 __NR_read
#define __NR_seccomp_write_32 __NR_write
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
#endif /* _ASM_POWERPC_SECCOMP_H */

View File

@ -22,6 +22,7 @@
#include <linux/kref.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/numa.h>
@ -322,18 +323,20 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp,
unsigned long app_cookie = 0;
unsigned int my_offset = 0;
struct vm_area_struct *vma;
struct file *exe_file;
struct mm_struct *mm = spu->mm;
if (!mm)
goto out;
down_read(&mm->mmap_sem);
if (mm->exe_file) {
app_cookie = fast_get_dcookie(&mm->exe_file->f_path);
pr_debug("got dcookie for %pD\n", mm->exe_file);
exe_file = get_mm_exe_file(mm);
if (exe_file) {
app_cookie = fast_get_dcookie(&exe_file->f_path);
pr_debug("got dcookie for %pD\n", exe_file);
fput(exe_file);
}
down_read(&mm->mmap_sem);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (vma->vm_start > spu_ref || vma->vm_end <= spu_ref)
continue;

View File

@ -1,15 +1,10 @@
#ifndef _ASM_SECCOMP_H
#define _ASM_SECCOMP_H
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#define __NR_seccomp_read_32 __NR_read
#define __NR_seccomp_write_32 __NR_write
#define __NR_seccomp_exit_32 __NR_exit
#define __NR_seccomp_sigreturn_32 __NR_sigreturn
#include <asm-generic/seccomp.h>
#endif /* _ASM_SECCOMP_H */

View File

@ -1,5 +1,20 @@
#ifndef _ASM_X86_SECCOMP_H
#define _ASM_X86_SECCOMP_H
#include <asm/unistd.h>
#ifdef CONFIG_X86_32
# include <asm/seccomp_32.h>
#else
# include <asm/seccomp_64.h>
#define __NR_seccomp_sigreturn __NR_sigreturn
#endif
#ifdef CONFIG_COMPAT
#include <asm/ia32_unistd.h>
#define __NR_seccomp_read_32 __NR_ia32_read
#define __NR_seccomp_write_32 __NR_ia32_write
#define __NR_seccomp_exit_32 __NR_ia32_exit
#define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn
#endif
#include <asm-generic/seccomp.h>
#endif /* _ASM_X86_SECCOMP_H */

View File

@ -1,11 +0,0 @@
#ifndef _ASM_X86_SECCOMP_32_H
#define _ASM_X86_SECCOMP_32_H
#include <linux/unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_sigreturn
#endif /* _ASM_X86_SECCOMP_32_H */

View File

@ -1,17 +0,0 @@
#ifndef _ASM_X86_SECCOMP_64_H
#define _ASM_X86_SECCOMP_64_H
#include <linux/unistd.h>
#include <asm/ia32_unistd.h>
#define __NR_seccomp_read __NR_read
#define __NR_seccomp_write __NR_write
#define __NR_seccomp_exit __NR_exit
#define __NR_seccomp_sigreturn __NR_rt_sigreturn
#define __NR_seccomp_read_32 __NR_ia32_read
#define __NR_seccomp_write_32 __NR_ia32_write
#define __NR_seccomp_exit_32 __NR_ia32_exit
#define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn
#endif /* _ASM_X86_SECCOMP_64_H */

View File

@ -15,6 +15,7 @@
#include "clk-kona.h"
#include <linux/delay.h>
#include <linux/kernel.h>
/*
* "Policies" affect the frequencies of bus clocks provided by a
@ -51,21 +52,6 @@ static inline u32 bitfield_replace(u32 reg_val, u32 shift, u32 width, u32 val)
/* Divider and scaling helpers */
/*
* Implement DIV_ROUND_CLOSEST() for 64-bit dividend and both values
* unsigned. Note that unlike do_div(), the remainder is discarded
* and the return value is the quotient (not the remainder).
*/
u64 do_div_round_closest(u64 dividend, unsigned long divisor)
{
u64 result;
result = dividend + ((u64)divisor >> 1);
(void)do_div(result, divisor);
return result;
}
/* Convert a divider into the scaled divisor value it represents. */
static inline u64 scaled_div_value(struct bcm_clk_div *div, u32 reg_div)
{
@ -87,7 +73,7 @@ u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, u32 billionths)
combined = (u64)div_value * BILLION + billionths;
combined <<= div->u.s.frac_width;
return do_div_round_closest(combined, BILLION);
return DIV_ROUND_CLOSEST_ULL(combined, BILLION);
}
/* The scaled minimum divisor representable by a divider */
@ -731,7 +717,7 @@ static unsigned long clk_recalc_rate(struct ccu_data *ccu,
scaled_rate = scale_rate(pre_div, parent_rate);
scaled_rate = scale_rate(div, scaled_rate);
scaled_div = divider_read_scaled(ccu, pre_div);
scaled_parent_rate = do_div_round_closest(scaled_rate,
scaled_parent_rate = DIV_ROUND_CLOSEST_ULL(scaled_rate,
scaled_div);
} else {
scaled_parent_rate = scale_rate(div, parent_rate);
@ -743,7 +729,7 @@ static unsigned long clk_recalc_rate(struct ccu_data *ccu,
* rate.
*/
scaled_div = divider_read_scaled(ccu, div);
result = do_div_round_closest(scaled_parent_rate, scaled_div);
result = DIV_ROUND_CLOSEST_ULL(scaled_parent_rate, scaled_div);
return (unsigned long)result;
}
@ -790,7 +776,7 @@ static long round_rate(struct ccu_data *ccu, struct bcm_clk_div *div,
scaled_rate = scale_rate(pre_div, parent_rate);
scaled_rate = scale_rate(div, scaled_rate);
scaled_pre_div = divider_read_scaled(ccu, pre_div);
scaled_parent_rate = do_div_round_closest(scaled_rate,
scaled_parent_rate = DIV_ROUND_CLOSEST_ULL(scaled_rate,
scaled_pre_div);
} else {
scaled_parent_rate = scale_rate(div, parent_rate);
@ -802,7 +788,7 @@ static long round_rate(struct ccu_data *ccu, struct bcm_clk_div *div,
* the best we can do.
*/
if (!divider_is_fixed(div)) {
best_scaled_div = do_div_round_closest(scaled_parent_rate,
best_scaled_div = DIV_ROUND_CLOSEST_ULL(scaled_parent_rate,
rate);
min_scaled_div = scaled_div_min(div);
max_scaled_div = scaled_div_max(div);
@ -815,7 +801,7 @@ static long round_rate(struct ccu_data *ccu, struct bcm_clk_div *div,
}
/* OK, figure out the resulting rate */
result = do_div_round_closest(scaled_parent_rate, best_scaled_div);
result = DIV_ROUND_CLOSEST_ULL(scaled_parent_rate, best_scaled_div);
if (scaled_div)
*scaled_div = best_scaled_div;

View File

@ -503,7 +503,6 @@ extern struct clk_ops kona_peri_clk_ops;
/* Externally visible functions */
extern u64 do_div_round_closest(u64 dividend, unsigned long divisor);
extern u64 scaled_div_max(struct bcm_clk_div *div);
extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value,
u32 billionths);

View File

@ -190,12 +190,6 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices);
static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */
static u64 div_round64(u64 dividend, u32 divisor)
{
return div_u64(dividend + (divisor / 2), divisor);
}
/*
* Try detecting repeating patterns by keeping track of the last 8
* intervals, and checking if the standard deviation of that set
@ -317,7 +311,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
* operands are 32 bits.
* Make sure to round up for half microseconds.
*/
data->predicted_us = div_round64((uint64_t)data->next_timer_us *
data->predicted_us = DIV_ROUND_CLOSEST_ULL((uint64_t)data->next_timer_us *
data->correction_factor[data->bucket],
RESOLUTION * DECAY);

View File

@ -36,9 +36,6 @@
#include <drm/drm_dp_mst_helper.h>
#include <drm/drm_rect.h>
#define DIV_ROUND_CLOSEST_ULL(ll, d) \
({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; })
/**
* _wait_for - magic (register) wait macro
*

View File

@ -30,6 +30,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include "intel_drv.h"

View File

@ -36,6 +36,7 @@
#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/delay.h>
#include <linux/util_macros.h>
#include <linux/platform_data/ina2xx.h>
@ -141,19 +142,6 @@ static const struct ina2xx_config ina2xx_config[] = {
*/
static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 };
static int ina226_avg_bits(int avg)
{
int i;
/* Get the closest average from the tab. */
for (i = 0; i < ARRAY_SIZE(ina226_avg_tab) - 1; i++) {
if (avg <= (ina226_avg_tab[i] + ina226_avg_tab[i + 1]) / 2)
break;
}
return i; /* Return 0b0111 for values greater than 1024. */
}
static int ina226_reg_to_interval(u16 config)
{
int avg = ina226_avg_tab[INA226_READ_AVG(config)];
@ -171,7 +159,8 @@ static u16 ina226_interval_to_reg(int interval, u16 config)
avg = DIV_ROUND_CLOSEST(interval * 1000,
INA226_TOTAL_CONV_TIME_DEFAULT);
avg_bits = ina226_avg_bits(avg);
avg_bits = find_closest(avg, ina226_avg_tab,
ARRAY_SIZE(ina226_avg_tab));
return (config & ~INA226_AVG_RD_MASK) | INA226_SHIFT_AVG(avg_bits);
}

View File

@ -34,6 +34,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/util_macros.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
@ -190,15 +191,7 @@ static const int lm85_range_map[] = {
static int RANGE_TO_REG(long range)
{
int i;
/* Find the closest match */
for (i = 0; i < 15; ++i) {
if (range <= (lm85_range_map[i] + lm85_range_map[i + 1]) / 2)
break;
}
return i;
return find_closest(range, lm85_range_map, ARRAY_SIZE(lm85_range_map));
}
#define RANGE_FROM_REG(val) lm85_range_map[(val) & 0x0f]
@ -209,16 +202,12 @@ static const int lm85_freq_map[8] = { /* 1 Hz */
static const int adm1027_freq_map[8] = { /* 1 Hz */
11, 15, 22, 29, 35, 44, 59, 88
};
#define FREQ_MAP_LEN 8
static int FREQ_TO_REG(const int *map, unsigned long freq)
static int FREQ_TO_REG(const int *map,
unsigned int map_size, unsigned long freq)
{
int i;
/* Find the closest match */
for (i = 0; i < 7; ++i)
if (freq <= (map[i] + map[i + 1]) / 2)
break;
return i;
return find_closest(freq, map, map_size);
}
static int FREQ_FROM_REG(const int *map, u8 reg)
@ -828,7 +817,8 @@ static ssize_t set_pwm_freq(struct device *dev,
data->cfg5 &= ~ADT7468_HFPWM;
lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5);
} else { /* Low freq. mode */
data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val);
data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map,
FREQ_MAP_LEN, val);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
(data->zone[nr].range << 4)
| data->pwm_freq[nr]);

View File

@ -35,6 +35,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/jiffies.h>
#include <linux/util_macros.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = {
@ -308,11 +309,8 @@ static u8 pwm_freq_to_reg(unsigned long val, u16 clkin)
unsigned long best0, best1;
/* Best fit for cksel = 0 */
for (reg0 = 0; reg0 < ARRAY_SIZE(pwm_freq_cksel0) - 1; reg0++) {
if (val > (pwm_freq_cksel0[reg0] +
pwm_freq_cksel0[reg0 + 1]) / 2)
break;
}
reg0 = find_closest_descending(val, pwm_freq_cksel0,
ARRAY_SIZE(pwm_freq_cksel0));
if (val < 375) /* cksel = 1 can't beat this */
return reg0;
best0 = pwm_freq_cksel0[reg0];

View File

@ -79,7 +79,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
num = if_freq / 1000; /* Hz => kHz */
num *= 0x4000;
if_ctl = 0x4000 - cxd2820r_div_u64_round_closest(num, 41000);
if_ctl = 0x4000 - DIV_ROUND_CLOSEST_ULL(num, 41000);
buf[0] = (if_ctl >> 8) & 0x3f;
buf[1] = (if_ctl >> 0) & 0xff;

View File

@ -244,12 +244,6 @@ int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio)
return ret;
}
/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
{
return div_u64(dividend + (divisor / 2), divisor);
}
static int cxd2820r_set_frontend(struct dvb_frontend *fe)
{
struct cxd2820r_priv *priv = fe->demodulator_priv;

View File

@ -64,8 +64,6 @@ int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
int len);
u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor);
int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
int len);

View File

@ -103,7 +103,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
num = if_freq / 1000; /* Hz => kHz */
num *= 0x1000000;
if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
if_ctl = DIV_ROUND_CLOSEST_ULL(num, 41000);
buf[0] = ((if_ctl >> 16) & 0xff);
buf[1] = ((if_ctl >> 8) & 0xff);
buf[2] = ((if_ctl >> 0) & 0xff);

View File

@ -120,7 +120,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
num = if_freq / 1000; /* Hz => kHz */
num *= 0x1000000;
if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
if_ctl = DIV_ROUND_CLOSEST_ULL(num, 41000);
buf[0] = ((if_ctl >> 16) & 0xff);
buf[1] = ((if_ctl >> 8) & 0xff);
buf[2] = ((if_ctl >> 0) & 0xff);

View File

@ -758,7 +758,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error)
if (error || (card->current_mrq.tpc == MSPRO_CMD_STOP)) {
if (msb->data_dir == READ) {
for (cnt = 0; cnt < msb->current_seg; cnt++)
for (cnt = 0; cnt < msb->current_seg; cnt++) {
t_len += msb->req_sg[cnt].length
/ msb->page_size;
@ -766,6 +766,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error)
t_len += msb->current_page - 1;
t_len *= msb->page_size;
}
}
} else
t_len = blk_rq_bytes(msb->block_req);

View File

@ -21,6 +21,7 @@
* objects.
*/
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/workqueue.h>
#include <linux/notifier.h>
@ -224,10 +225,18 @@ static inline unsigned long fast_get_dcookie(struct path *path)
static unsigned long get_exec_dcookie(struct mm_struct *mm)
{
unsigned long cookie = NO_COOKIE;
struct file *exe_file;
if (mm && mm->exe_file)
cookie = fast_get_dcookie(&mm->exe_file->f_path);
if (!mm)
goto done;
exe_file = get_mm_exe_file(mm);
if (!exe_file)
goto done;
cookie = fast_get_dcookie(&exe_file->f_path);
fput(exe_file);
done:
return cookie;
}
@ -236,6 +245,8 @@ static unsigned long get_exec_dcookie(struct mm_struct *mm)
* pair that can then be added to the global event buffer. We make
* sure to do this lookup before a mm->mmap modification happens so
* we don't lose track.
*
* The caller must ensure the mm is not nil (ie: not a kernel thread).
*/
static unsigned long
lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset)
@ -243,6 +254,7 @@ lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset)
unsigned long cookie = NO_COOKIE;
struct vm_area_struct *vma;
down_read(&mm->mmap_sem);
for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
if (addr < vma->vm_start || addr >= vma->vm_end)
@ -262,6 +274,7 @@ lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset)
if (!vma)
cookie = INVALID_COOKIE;
up_read(&mm->mmap_sem);
return cookie;
}
@ -402,20 +415,9 @@ static void release_mm(struct mm_struct *mm)
{
if (!mm)
return;
up_read(&mm->mmap_sem);
mmput(mm);
}
static struct mm_struct *take_tasks_mm(struct task_struct *task)
{
struct mm_struct *mm = get_task_mm(task);
if (mm)
down_read(&mm->mmap_sem);
return mm;
}
static inline int is_code(unsigned long val)
{
return val == ESCAPE_CODE;
@ -532,7 +534,7 @@ void sync_buffer(int cpu)
new = (struct task_struct *)val;
oldmm = mm;
release_mm(oldmm);
mm = take_tasks_mm(new);
mm = get_task_mm(new);
if (mm != oldmm)
cookie = get_exec_dcookie(mm);
add_user_ctx_switch(new, cookie);

View File

@ -1111,6 +1111,16 @@ config RTC_DRV_DAVINCI
This driver can also be built as a module. If so, the module
will be called rtc-davinci.
config RTC_DRV_DIGICOLOR
tristate "Conexant Digicolor RTC"
depends on ARCH_DIGICOLOR
help
If you say yes here you get support for the RTC on Conexant
Digicolor platforms. This currently includes the CX92755 SoC.
This driver can also be built as a module. If so, the module
will be called rtc-digicolor.
config RTC_DRV_IMXDI
tristate "Freescale IMX DryIce Real Time Clock"
depends on ARCH_MXC
@ -1121,11 +1131,11 @@ config RTC_DRV_IMXDI
will be called "rtc-imxdi".
config RTC_DRV_OMAP
tristate "TI OMAP1"
depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX || SOC_AM33XX
tristate "TI OMAP Real Time Clock"
depends on ARCH_OMAP || ARCH_DAVINCI
help
Say "yes" here to support the on chip real time clock
present on TI OMAP1, AM33xx and DA8xx/OMAP-L13x.
present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx.
This driver can also be built as a module, if so, module
will be called rtc-omap.

View File

@ -40,6 +40,7 @@ obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o
obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o
obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o
obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o
obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o

View File

@ -221,15 +221,15 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
rtc->pie_timer.function = rtc_pie_update_irq;
rtc->pie_enabled = 0;
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
dev_set_name(&rtc->dev, "rtc%d", id);
/* Check to see if there is an ALARM already set in hw */
err = __rtc_read_alarm(rtc, &alrm);
if (!err && !rtc_valid_tm(&alrm.time))
rtc_initialize_alarm(rtc, &alrm);
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
dev_set_name(&rtc->dev, "rtc%d", id);
rtc_dev_prepare(rtc);
err = device_register(&rtc->dev);

View File

@ -9,6 +9,8 @@
* published by the Free Software Foundation.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/rtc.h>
/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
@ -32,8 +34,8 @@ static int __init rtc_hctosys(void)
struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
if (rtc == NULL) {
pr_err("%s: unable to open rtc device (%s)\n",
__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
pr_info("unable to open rtc device (%s)\n",
CONFIG_RTC_HCTOSYS_DEVICE);
goto err_open;
}

View File

@ -31,13 +31,14 @@ static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
memset(tm, 0, sizeof(struct rtc_time));
err = rtc->ops->read_time(rtc->dev.parent, tm);
if (err < 0) {
dev_err(&rtc->dev, "read_time: fail to read\n");
dev_dbg(&rtc->dev, "read_time: fail to read: %d\n",
err);
return err;
}
err = rtc_valid_tm(tm);
if (err < 0)
dev_err(&rtc->dev, "read_time: rtc_time isn't valid\n");
dev_dbg(&rtc->dev, "read_time: rtc_time isn't valid\n");
}
return err;
}

View File

@ -881,7 +881,7 @@ static const struct rtc_class_ops rtc_ops = {
.alarm_irq_enable = abb5zes3_rtc_alarm_irq_enable,
};
static struct regmap_config abb5zes3_rtc_regmap_config = {
static const struct regmap_config abb5zes3_rtc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};

View File

@ -37,9 +37,9 @@
#include "rtc-at91rm9200.h"
#define at91_rtc_read(field) \
__raw_readl(at91_rtc_regs + field)
readl_relaxed(at91_rtc_regs + field)
#define at91_rtc_write(field, val) \
__raw_writel((val), at91_rtc_regs + field)
writel_relaxed((val), at91_rtc_regs + field)
#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */

View File

@ -28,6 +28,9 @@
* interrupts disabled, holding the global rtc_lock, to exclude those
* other drivers and utilities on correctly configured systems.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@ -385,8 +388,7 @@ static bool alarm_disable_quirk;
static int __init set_alarm_disable_quirk(const struct dmi_system_id *id)
{
alarm_disable_quirk = true;
pr_info("rtc-cmos: BIOS has alarm-disable quirk. ");
pr_info("RTC alarms disabled\n");
pr_info("BIOS has alarm-disable quirk - RTC alarms disabled\n");
return 0;
}

View File

@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/reg.h>
@ -23,6 +24,8 @@
#define rtc_err(rtc, fmt, ...) \
dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
#define DA9052_GET_TIME_RETRIES 5
struct da9052_rtc {
struct rtc_device *rtc;
struct da9052 *da9052;
@ -58,22 +61,43 @@ static irqreturn_t da9052_rtc_irq(int irq, void *data)
static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
{
int ret;
uint8_t v[5];
uint8_t v[2][5];
int idx = 1;
int timeout = DA9052_GET_TIME_RETRIES;
ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, v);
if (ret != 0) {
ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, &v[0][0]);
if (ret) {
rtc_err(rtc, "Failed to group read ALM: %d\n", ret);
return ret;
}
rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100;
rtc_tm->tm_mon = (v[3] & DA9052_RTC_MONTH) - 1;
rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY;
rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR;
rtc_tm->tm_min = v[0] & DA9052_RTC_MIN;
do {
ret = da9052_group_read(rtc->da9052,
DA9052_ALARM_MI_REG, 5, &v[idx][0]);
if (ret) {
rtc_err(rtc, "Failed to group read ALM: %d\n", ret);
return ret;
}
ret = rtc_valid_tm(rtc_tm);
return ret;
if (memcmp(&v[0][0], &v[1][0], 5) == 0) {
rtc_tm->tm_year = (v[0][4] & DA9052_RTC_YEAR) + 100;
rtc_tm->tm_mon = (v[0][3] & DA9052_RTC_MONTH) - 1;
rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY;
rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR;
rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN;
ret = rtc_valid_tm(rtc_tm);
return ret;
}
idx = (1-idx);
msleep(20);
} while (timeout--);
rtc_err(rtc, "Timed out reading alarm time\n");
return -EIO;
}
static int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
@ -135,24 +159,45 @@ static int da9052_rtc_get_alarm_status(struct da9052_rtc *rtc)
static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
{
struct da9052_rtc *rtc = dev_get_drvdata(dev);
uint8_t v[6];
int ret;
uint8_t v[2][6];
int idx = 1;
int timeout = DA9052_GET_TIME_RETRIES;
ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
if (ret < 0) {
ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, &v[0][0]);
if (ret) {
rtc_err(rtc, "Failed to read RTC time : %d\n", ret);
return ret;
}
rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100;
rtc_tm->tm_mon = (v[4] & DA9052_RTC_MONTH) - 1;
rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY;
rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR;
rtc_tm->tm_min = v[1] & DA9052_RTC_MIN;
rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC;
do {
ret = da9052_group_read(rtc->da9052,
DA9052_COUNT_S_REG, 6, &v[idx][0]);
if (ret) {
rtc_err(rtc, "Failed to read RTC time : %d\n", ret);
return ret;
}
ret = rtc_valid_tm(rtc_tm);
return ret;
if (memcmp(&v[0][0], &v[1][0], 6) == 0) {
rtc_tm->tm_year = (v[0][5] & DA9052_RTC_YEAR) + 100;
rtc_tm->tm_mon = (v[0][4] & DA9052_RTC_MONTH) - 1;
rtc_tm->tm_mday = v[0][3] & DA9052_RTC_DAY;
rtc_tm->tm_hour = v[0][2] & DA9052_RTC_HOUR;
rtc_tm->tm_min = v[0][1] & DA9052_RTC_MIN;
rtc_tm->tm_sec = v[0][0] & DA9052_RTC_SEC;
ret = rtc_valid_tm(rtc_tm);
return ret;
}
idx = (1-idx);
msleep(20);
} while (timeout--);
rtc_err(rtc, "Timed out reading time\n");
return -EIO;
}
static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
@ -161,6 +206,10 @@ static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
uint8_t v[6];
int ret;
/* DA9052 only has 6 bits for year - to represent 2000-2063 */
if ((tm->tm_year < 100) || (tm->tm_year > 163))
return -EINVAL;
rtc = dev_get_drvdata(dev);
v[0] = tm->tm_sec;
@ -198,6 +247,10 @@ static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_time *tm = &alrm->time;
struct da9052_rtc *rtc = dev_get_drvdata(dev);
/* DA9052 only has 6 bits for year - to represent 2000-2063 */
if ((tm->tm_year < 100) || (tm->tm_year > 163))
return -EINVAL;
ret = da9052_rtc_enable_alarm(rtc, 0);
if (ret < 0)
return ret;
@ -256,6 +309,8 @@ static int da9052_rtc_probe(struct platform_device *pdev)
return ret;
}
device_init_wakeup(&pdev->dev, true);
rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&da9052_rtc_ops, THIS_MODULE);
return PTR_ERR_OR_ZERO(rtc->rtc);

227
drivers/rtc/rtc-digicolor.c Normal file
View File

@ -0,0 +1,227 @@
/*
* Real Time Clock driver for Conexant Digicolor
*
* Copyright (C) 2015 Paradox Innovation Ltd.
*
* Author: Baruch Siach <baruch@tkos.co.il>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/of.h>
#define DC_RTC_CONTROL 0x0
#define DC_RTC_TIME 0x8
#define DC_RTC_REFERENCE 0xc
#define DC_RTC_ALARM 0x10
#define DC_RTC_INTFLAG_CLEAR 0x14
#define DC_RTC_INTENABLE 0x16
#define DC_RTC_CMD_MASK 0xf
#define DC_RTC_GO_BUSY BIT(7)
#define CMD_NOP 0
#define CMD_RESET 1
#define CMD_WRITE 3
#define CMD_READ 4
#define CMD_DELAY_US (10*1000)
#define CMD_TIMEOUT_US (500*CMD_DELAY_US)
struct dc_rtc {
struct rtc_device *rtc_dev;
void __iomem *regs;
};
static int dc_rtc_cmds(struct dc_rtc *rtc, const u8 *cmds, int len)
{
u8 val;
int i, ret;
for (i = 0; i < len; i++) {
writeb_relaxed((cmds[i] & DC_RTC_CMD_MASK) | DC_RTC_GO_BUSY,
rtc->regs + DC_RTC_CONTROL);
ret = readb_relaxed_poll_timeout(
rtc->regs + DC_RTC_CONTROL, val,
!(val & DC_RTC_GO_BUSY), CMD_DELAY_US, CMD_TIMEOUT_US);
if (ret < 0)
return ret;
}
return 0;
}
static int dc_rtc_read(struct dc_rtc *rtc, unsigned long *val)
{
static const u8 read_cmds[] = {CMD_READ, CMD_NOP};
u32 reference, time1, time2;
int ret;
ret = dc_rtc_cmds(rtc, read_cmds, ARRAY_SIZE(read_cmds));
if (ret < 0)
return ret;
reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
time1 = readl_relaxed(rtc->regs + DC_RTC_TIME);
/* Read twice to ensure consistency */
while (1) {
time2 = readl_relaxed(rtc->regs + DC_RTC_TIME);
if (time1 == time2)
break;
time1 = time2;
}
*val = reference + time1;
return 0;
}
static int dc_rtc_write(struct dc_rtc *rtc, u32 val)
{
static const u8 write_cmds[] = {CMD_WRITE, CMD_NOP, CMD_RESET, CMD_NOP};
writel_relaxed(val, rtc->regs + DC_RTC_REFERENCE);
return dc_rtc_cmds(rtc, write_cmds, ARRAY_SIZE(write_cmds));
}
static int dc_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct dc_rtc *rtc = dev_get_drvdata(dev);
unsigned long now;
int ret;
ret = dc_rtc_read(rtc, &now);
if (ret < 0)
return ret;
rtc_time64_to_tm(now, tm);
return 0;
}
static int dc_rtc_set_mmss(struct device *dev, unsigned long secs)
{
struct dc_rtc *rtc = dev_get_drvdata(dev);
return dc_rtc_write(rtc, secs);
}
static int dc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct dc_rtc *rtc = dev_get_drvdata(dev);
u32 alarm_reg, reference;
unsigned long now;
int ret;
alarm_reg = readl_relaxed(rtc->regs + DC_RTC_ALARM);
reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
rtc_time64_to_tm(reference + alarm_reg, &alarm->time);
ret = dc_rtc_read(rtc, &now);
if (ret < 0)
return ret;
alarm->pending = alarm_reg + reference > now;
alarm->enabled = readl_relaxed(rtc->regs + DC_RTC_INTENABLE);
return 0;
}
static int dc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct dc_rtc *rtc = dev_get_drvdata(dev);
time64_t alarm_time;
u32 reference;
alarm_time = rtc_tm_to_time64(&alarm->time);
reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE);
writel_relaxed(alarm_time - reference, rtc->regs + DC_RTC_ALARM);
writeb_relaxed(!!alarm->enabled, rtc->regs + DC_RTC_INTENABLE);
return 0;
}
static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct dc_rtc *rtc = dev_get_drvdata(dev);
writeb_relaxed(!!enabled, rtc->regs + DC_RTC_INTENABLE);
return 0;
}
static struct rtc_class_ops dc_rtc_ops = {
.read_time = dc_rtc_read_time,
.set_mmss = dc_rtc_set_mmss,
.read_alarm = dc_rtc_read_alarm,
.set_alarm = dc_rtc_set_alarm,
.alarm_irq_enable = dc_rtc_alarm_irq_enable,
};
static irqreturn_t dc_rtc_irq(int irq, void *dev_id)
{
struct dc_rtc *rtc = dev_id;
writeb_relaxed(1, rtc->regs + DC_RTC_INTFLAG_CLEAR);
rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
return IRQ_HANDLED;
}
static int __init dc_rtc_probe(struct platform_device *pdev)
{
struct resource *res;
struct dc_rtc *rtc;
int irq, ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rtc->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(rtc->regs))
return PTR_ERR(rtc->regs);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
ret = devm_request_irq(&pdev->dev, irq, dc_rtc_irq, 0, pdev->name, rtc);
if (ret < 0)
return ret;
platform_set_drvdata(pdev, rtc);
rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
&dc_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev))
return PTR_ERR(rtc->rtc_dev);
return 0;
}
static const struct of_device_id dc_dt_ids[] = {
{ .compatible = "cnxt,cx92755-rtc" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dc_dt_ids);
static struct platform_driver dc_rtc_driver = {
.driver = {
.name = "digicolor_rtc",
.of_match_table = of_match_ptr(dc_dt_ids),
},
};
module_platform_driver_probe(dc_rtc_driver, dc_rtc_probe);
MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
MODULE_DESCRIPTION("Conexant Digicolor Realtime Clock Driver (RTC)");
MODULE_LICENSE("GPL");

View File

@ -18,6 +18,8 @@
* "Sending and receiving", using SMBus level communication is preferred.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
@ -406,7 +408,7 @@ static int ds1374_wdt_settimeout(unsigned int timeout)
/* Set new watchdog time */
ret = ds1374_write_rtc(save_client, timeout, DS1374_REG_WDALM0, 3);
if (ret) {
pr_info("rtc-ds1374 - couldn't set new watchdog time\n");
pr_info("couldn't set new watchdog time\n");
goto out;
}
@ -539,12 +541,12 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
pr_info("rtc-ds1374: disable watchdog\n");
pr_info("disable watchdog\n");
ds1374_wdt_disable();
}
if (options & WDIOS_ENABLECARD) {
pr_info("rtc-ds1374: enable watchdog\n");
pr_info("enable watchdog\n");
ds1374_wdt_settimeout(wdt_margin);
ds1374_wdt_ping();
}

View File

@ -16,6 +16,8 @@
* published by the Free Software Foundation.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bcd.h>
#include <linux/delay.h>
#include <linux/io.h>
@ -799,7 +801,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq)
struct platform_device *pdev = to_platform_device(dev);
struct ds1685_priv *rtc = platform_get_drvdata(pdev);
u8 ctrla, ctrlb, ctrlc, ctrld, ctrl4a, ctrl4b, ssn[8];
char *model = '\0';
char *model;
#ifdef CONFIG_RTC_DS1685_PROC_REGS
char bits[NUM_REGS][(NUM_BITS * NUM_SPACES) + NUM_BITS + 1];
#endif
@ -2139,7 +2141,6 @@ ds1685_rtc_remove(struct platform_device *pdev)
static struct platform_driver ds1685_rtc_driver = {
.driver = {
.name = "rtc-ds1685",
.owner = THIS_MODULE,
},
.probe = ds1685_rtc_probe,
.remove = ds1685_rtc_remove,
@ -2175,7 +2176,7 @@ module_exit(ds1685_rtc_exit);
* ds1685_rtc_poweroff - uses the RTC chip to power the system off.
* @pdev: pointer to platform_device structure.
*/
extern void __noreturn
void __noreturn
ds1685_rtc_poweroff(struct platform_device *pdev)
{
u8 ctrla, ctrl4a, ctrl4b;
@ -2183,7 +2184,7 @@ ds1685_rtc_poweroff(struct platform_device *pdev)
/* Check for valid RTC data, else, spin forever. */
if (unlikely(!pdev)) {
pr_emerg("rtc-ds1685: platform device data not available, spinning forever ...\n");
pr_emerg("platform device data not available, spinning forever ...\n");
unreachable();
} else {
/* Get the rtc data. */

View File

@ -15,6 +15,8 @@
* "Sending and receiving", using SMBus level communication is preferred.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
@ -373,8 +375,8 @@ static void ds3232_work(struct work_struct *work)
if (stat & DS3232_REG_SR_A1F) {
control = i2c_smbus_read_byte_data(client, DS3232_REG_CR);
if (control < 0) {
pr_warn("Read DS3232 Control Register error."
"Disable IRQ%d.\n", client->irq);
pr_warn("Read Control Register error - Disable IRQ%d\n",
client->irq);
} else {
/* disable alarm1 interrupt */
control &= ~(DS3232_REG_CR_A1IE);

View File

@ -8,6 +8,9 @@
* Copyright (C) 1999-2000 VA Linux Systems
* Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

View File

@ -15,6 +15,7 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/module.h>
#include <linux/of.h>
/* Registers */
#define EM3027_REG_ON_OFF_CTRL 0x00
@ -135,10 +136,20 @@ static struct i2c_device_id em3027_id[] = {
{ "em3027", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, em3027_id);
#ifdef CONFIG_OF
static const struct of_device_id em3027_of_match[] = {
{ .compatible = "emmicro,em3027", },
{}
};
MODULE_DEVICE_TABLE(of, em3027_of_match);
#endif
static struct i2c_driver em3027_driver = {
.driver = {
.name = "rtc-em3027",
.of_match_table = of_match_ptr(em3027_of_match),
},
.probe = &em3027_probe,
.id_table = em3027_id,

View File

@ -66,7 +66,7 @@
#define HYM8563_ALM_BIT_DISABLE BIT(7)
#define HYM8563_CLKOUT 0x0d
#define HYM8563_CLKOUT_DISABLE BIT(7)
#define HYM8563_CLKOUT_ENABLE BIT(7)
#define HYM8563_CLKOUT_32768 0
#define HYM8563_CLKOUT_1024 1
#define HYM8563_CLKOUT_32 2
@ -309,7 +309,7 @@ static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw,
struct i2c_client *client = hym8563->client;
int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
if (ret < 0 || ret & HYM8563_CLKOUT_DISABLE)
if (ret < 0)
return 0;
ret &= HYM8563_CLKOUT_MASK;
@ -360,9 +360,9 @@ static int hym8563_clkout_control(struct clk_hw *hw, bool enable)
return ret;
if (enable)
ret &= ~HYM8563_CLKOUT_DISABLE;
ret |= HYM8563_CLKOUT_ENABLE;
else
ret |= HYM8563_CLKOUT_DISABLE;
ret &= ~HYM8563_CLKOUT_ENABLE;
return i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, ret);
}
@ -386,7 +386,7 @@ static int hym8563_clkout_is_prepared(struct clk_hw *hw)
if (ret < 0)
return ret;
return !(ret & HYM8563_CLKOUT_DISABLE);
return !!(ret & HYM8563_CLKOUT_ENABLE);
}
static const struct clk_ops hym8563_clkout_ops = {
@ -407,7 +407,7 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
int ret;
ret = i2c_smbus_write_byte_data(client, HYM8563_CLKOUT,
HYM8563_CLKOUT_DISABLE);
0);
if (ret < 0)
return ERR_PTR(ret);

View File

@ -13,6 +13,8 @@
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bcd.h>
#include <linux/i2c.h>
#include <linux/init.h>
@ -513,12 +515,12 @@ static int wdt_ioctl(struct file *file, unsigned int cmd,
return -EFAULT;
if (rv & WDIOS_DISABLECARD) {
pr_info("rtc-m41t80: disable watchdog\n");
pr_info("disable watchdog\n");
wdt_disable();
}
if (rv & WDIOS_ENABLECARD) {
pr_info("rtc-m41t80: enable watchdog\n");
pr_info("enable watchdog\n");
wdt_ping();
}

View File

@ -12,6 +12,8 @@
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/delay.h>
@ -103,8 +105,8 @@ static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
if (tm->tm_year < 100) {
pr_warn("%s: MAX77686 RTC cannot handle the year %d."
"Assume it's 2000.\n", __func__, 1900 + tm->tm_year);
pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n",
1900 + tm->tm_year);
return -EINVAL;
}
return 0;

View File

@ -12,6 +12,8 @@
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/delay.h>
@ -107,8 +109,8 @@ static int max8997_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
if (tm->tm_year < 100) {
pr_warn("%s: MAX8997 RTC cannot handle the year %d."
"Assume it's 2000.\n", __func__, 1900 + tm->tm_year);
pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n",
1900 + tm->tm_year);
return -EINVAL;
}
return 0;
@ -424,7 +426,7 @@ static void max8997_rtc_enable_smpl(struct max8997_rtc_info *info, bool enable)
val = 0;
max8997_read_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, &val);
pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val);
pr_info("WTSR_SMPL(0x%02x)\n", val);
}
static int max8997_rtc_init_reg(struct max8997_rtc_info *info)

View File

@ -7,6 +7,8 @@
* Copyright (C) 1993 Hamish Macdonald
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/kernel.h>
@ -111,7 +113,7 @@ static void msm6242_lock(struct msm6242_priv *priv)
}
if (!cnt)
pr_warn("msm6242: timed out waiting for RTC (0x%x)\n",
pr_warn("timed out waiting for RTC (0x%x)\n",
msm6242_read(priv, MSM6242_CD));
}

View File

@ -118,12 +118,15 @@
#define KICK0_VALUE 0x83e70b13
#define KICK1_VALUE 0x95a4f1e0
struct omap_rtc;
struct omap_rtc_device_type {
bool has_32kclk_en;
bool has_kicker;
bool has_irqwakeen;
bool has_pmic_mode;
bool has_power_up_reset;
void (*lock)(struct omap_rtc *rtc);
void (*unlock)(struct omap_rtc *rtc);
};
struct omap_rtc {
@ -156,6 +159,26 @@ static inline void rtc_writel(struct omap_rtc *rtc, unsigned int reg, u32 val)
writel(val, rtc->base + reg);
}
static void am3352_rtc_unlock(struct omap_rtc *rtc)
{
rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE);
rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE);
}
static void am3352_rtc_lock(struct omap_rtc *rtc)
{
rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
rtc_writel(rtc, OMAP_RTC_KICK1_REG, 0);
}
static void default_rtc_unlock(struct omap_rtc *rtc)
{
}
static void default_rtc_lock(struct omap_rtc *rtc)
{
}
/*
* We rely on the rtc framework to handle locking (rtc->ops_lock),
* so the only other requirement is that register accesses which
@ -186,7 +209,9 @@ static irqreturn_t rtc_irq(int irq, void *dev_id)
/* alarm irq? */
if (irq_data & OMAP_RTC_STATUS_ALARM) {
rtc->type->unlock(rtc);
rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM);
rtc->type->lock(rtc);
events |= RTC_IRQF | RTC_AF;
}
@ -218,9 +243,11 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
}
rtc_wait_not_busy(rtc);
rtc->type->unlock(rtc);
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
if (rtc->type->has_irqwakeen)
rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
rtc->type->lock(rtc);
local_irq_enable();
return 0;
@ -293,12 +320,14 @@ static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm)
local_irq_disable();
rtc_wait_not_busy(rtc);
rtc->type->unlock(rtc);
rtc_write(rtc, OMAP_RTC_YEARS_REG, tm->tm_year);
rtc_write(rtc, OMAP_RTC_MONTHS_REG, tm->tm_mon);
rtc_write(rtc, OMAP_RTC_DAYS_REG, tm->tm_mday);
rtc_write(rtc, OMAP_RTC_HOURS_REG, tm->tm_hour);
rtc_write(rtc, OMAP_RTC_MINUTES_REG, tm->tm_min);
rtc_write(rtc, OMAP_RTC_SECONDS_REG, tm->tm_sec);
rtc->type->lock(rtc);
local_irq_enable();
@ -341,6 +370,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
local_irq_disable();
rtc_wait_not_busy(rtc);
rtc->type->unlock(rtc);
rtc_write(rtc, OMAP_RTC_ALARM_YEARS_REG, alm->time.tm_year);
rtc_write(rtc, OMAP_RTC_ALARM_MONTHS_REG, alm->time.tm_mon);
rtc_write(rtc, OMAP_RTC_ALARM_DAYS_REG, alm->time.tm_mday);
@ -362,6 +392,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
if (rtc->type->has_irqwakeen)
rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
rtc->type->lock(rtc);
local_irq_enable();
@ -391,6 +422,7 @@ static void omap_rtc_power_off(void)
unsigned long now;
u32 val;
rtc->type->unlock(rtc);
/* enable pmic_power_en control */
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
@ -423,6 +455,7 @@ static void omap_rtc_power_off(void)
val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
rtc->type->lock(rtc);
/*
* Wait for alarm to trigger (within two seconds) and external PMIC to
@ -442,17 +475,21 @@ static struct rtc_class_ops omap_rtc_ops = {
static const struct omap_rtc_device_type omap_rtc_default_type = {
.has_power_up_reset = true,
.lock = default_rtc_lock,
.unlock = default_rtc_unlock,
};
static const struct omap_rtc_device_type omap_rtc_am3352_type = {
.has_32kclk_en = true,
.has_kicker = true,
.has_irqwakeen = true,
.has_pmic_mode = true,
.lock = am3352_rtc_lock,
.unlock = am3352_rtc_unlock,
};
static const struct omap_rtc_device_type omap_rtc_da830_type = {
.has_kicker = true,
.lock = am3352_rtc_lock,
.unlock = am3352_rtc_unlock,
};
static const struct platform_device_id omap_rtc_id_table[] = {
@ -484,7 +521,7 @@ static const struct of_device_id omap_rtc_of_match[] = {
};
MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
static int __init omap_rtc_probe(struct platform_device *pdev)
static int omap_rtc_probe(struct platform_device *pdev)
{
struct omap_rtc *rtc;
struct resource *res;
@ -527,10 +564,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
if (rtc->type->has_kicker) {
rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE);
rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE);
}
rtc->type->unlock(rtc);
/*
* disable interrupts
@ -593,6 +627,8 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
if (reg != new_ctrl)
rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl);
rtc->type->lock(rtc);
device_init_wakeup(&pdev->dev, true);
rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
@ -626,8 +662,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
err:
device_init_wakeup(&pdev->dev, false);
if (rtc->type->has_kicker)
rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
rtc->type->lock(rtc);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
@ -646,11 +681,11 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 0);
rtc->type->unlock(rtc);
/* leave rtc running, but disable irqs */
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
if (rtc->type->has_kicker)
rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
rtc->type->lock(rtc);
/* Disable the clock/module */
pm_runtime_put_sync(&pdev->dev);
@ -666,6 +701,7 @@ static int omap_rtc_suspend(struct device *dev)
rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
rtc->type->unlock(rtc);
/*
* FIXME: the RTC alarm is not currently acting as a wakeup event
* source on some platforms, and in fact this enable() call is just
@ -675,6 +711,7 @@ static int omap_rtc_suspend(struct device *dev)
enable_irq_wake(rtc->irq_alarm);
else
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
rtc->type->lock(rtc);
/* Disable the clock/module */
pm_runtime_put_sync(dev);
@ -689,10 +726,12 @@ static int omap_rtc_resume(struct device *dev)
/* Enable the clock/module so that we can access the registers */
pm_runtime_get_sync(dev);
rtc->type->unlock(rtc);
if (device_may_wakeup(dev))
disable_irq_wake(rtc->irq_alarm);
else
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg);
rtc->type->lock(rtc);
return 0;
}
@ -709,12 +748,15 @@ static void omap_rtc_shutdown(struct platform_device *pdev)
* Keep the ALARM interrupt enabled to allow the system to power up on
* alarm events.
*/
rtc->type->unlock(rtc);
mask = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
mask &= OMAP_RTC_INTERRUPTS_IT_ALARM;
rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, mask);
rtc->type->lock(rtc);
}
static struct platform_driver omap_rtc_driver = {
.probe = omap_rtc_probe,
.remove = __exit_p(omap_rtc_remove),
.shutdown = omap_rtc_shutdown,
.driver = {
@ -725,7 +767,7 @@ static struct platform_driver omap_rtc_driver = {
.id_table = omap_rtc_id_table,
};
module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe);
module_platform_driver(omap_rtc_driver);
MODULE_ALIAS("platform:omap_rtc");
MODULE_AUTHOR("George G. Davis (and others)");

View File

@ -16,8 +16,9 @@
* along with this program.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define DRVNAME "rtc-opal"
#define pr_fmt(fmt) DRVNAME ": " fmt
#include <linux/module.h>
#include <linux/err.h>

View File

@ -246,7 +246,6 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
int err;
unsigned char buf[9];
dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
@ -272,12 +271,8 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
err = pcf8563_write_block_data(client, PCF8563_REG_SC,
return pcf8563_write_block_data(client, PCF8563_REG_SC,
9 - PCF8563_REG_SC, buf + PCF8563_REG_SC);
if (err)
return err;
return 0;
}
#ifdef CONFIG_RTC_INTF_DEV

View File

@ -39,7 +39,6 @@ struct s3c_rtc {
void __iomem *base;
struct clk *rtc_clk;
struct clk *rtc_src_clk;
bool enabled;
struct s3c_rtc_data *data;
@ -67,26 +66,25 @@ struct s3c_rtc_data {
void (*disable) (struct s3c_rtc *info);
};
static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable)
static void s3c_rtc_enable_clk(struct s3c_rtc *info)
{
unsigned long irq_flags;
spin_lock_irqsave(&info->alarm_clk_lock, irq_flags);
if (enable) {
if (!info->enabled) {
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
info->enabled = true;
}
} else {
if (info->enabled) {
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
info->enabled = false;
}
}
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags);
}
static void s3c_rtc_disable_clk(struct s3c_rtc *info)
{
unsigned long irq_flags;
spin_lock_irqsave(&info->alarm_clk_lock, irq_flags);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags);
}
@ -119,20 +117,16 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled);
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
s3c_rtc_enable_clk(info);
tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN;
if (enabled)
tmp |= S3C2410_RTCALM_ALMEN;
writeb(tmp, info->base + S3C2410_RTCALM);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
s3c_rtc_alarm_clk_enable(info, enabled);
s3c_rtc_disable_clk(info);
return 0;
}
@ -143,18 +137,12 @@ static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq)
if (!is_power_of_2(freq))
return -EINVAL;
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
spin_lock_irq(&info->pie_lock);
if (info->data->set_freq)
info->data->set_freq(info, freq);
spin_unlock_irq(&info->pie_lock);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
return 0;
}
@ -165,9 +153,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
struct s3c_rtc *info = dev_get_drvdata(dev);
unsigned int have_retried = 0;
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
s3c_rtc_enable_clk(info);
retry_get_time:
rtc_tm->tm_min = readb(info->base + S3C2410_RTCMIN);
@ -194,6 +180,8 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
s3c_rtc_disable_clk(info);
rtc_tm->tm_year += 100;
dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n",
@ -202,10 +190,6 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_mon -= 1;
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
return rtc_valid_tm(rtc_tm);
}
@ -225,9 +209,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
return -EINVAL;
}
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
s3c_rtc_enable_clk(info);
writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC);
writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN);
@ -236,9 +218,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON);
writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
s3c_rtc_disable_clk(info);
return 0;
}
@ -249,9 +229,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_time *alm_tm = &alrm->time;
unsigned int alm_en;
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
s3c_rtc_enable_clk(info);
alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC);
alm_tm->tm_min = readb(info->base + S3C2410_ALMMIN);
@ -262,6 +240,8 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
alm_en = readb(info->base + S3C2410_RTCALM);
s3c_rtc_disable_clk(info);
alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n",
@ -269,9 +249,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
/* decode the alarm enable field */
if (alm_en & S3C2410_RTCALM_SECEN)
alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
else
@ -304,10 +282,6 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
else
alm_tm->tm_year = -1;
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
return 0;
}
@ -317,15 +291,13 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
struct rtc_time *tm = &alrm->time;
unsigned int alrm_en;
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n",
alrm->enabled,
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
s3c_rtc_enable_clk(info);
alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN;
writeb(0x00, info->base + S3C2410_RTCALM);
@ -348,11 +320,9 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
writeb(alrm_en, info->base + S3C2410_RTCALM);
s3c_rtc_setaie(dev, alrm->enabled);
s3c_rtc_disable_clk(info);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
s3c_rtc_setaie(dev, alrm->enabled);
return 0;
}
@ -361,16 +331,12 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
{
struct s3c_rtc *info = dev_get_drvdata(dev);
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
s3c_rtc_enable_clk(info);
if (info->data->enable_tick)
info->data->enable_tick(info, seq);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
s3c_rtc_disable_clk(info);
return 0;
}
@ -388,10 +354,6 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info)
{
unsigned int con, tmp;
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
con = readw(info->base + S3C2410_RTCCON);
/* re-enable the device, and check it is ok */
if ((con & S3C2410_RTCCON_RTCEN) == 0) {
@ -417,20 +379,12 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info)
writew(tmp & ~S3C2410_RTCCON_CLKRST,
info->base + S3C2410_RTCCON);
}
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
}
static void s3c24xx_rtc_disable(struct s3c_rtc *info)
{
unsigned int con;
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
con = readw(info->base + S3C2410_RTCCON);
con &= ~S3C2410_RTCCON_RTCEN;
writew(con, info->base + S3C2410_RTCCON);
@ -438,28 +392,16 @@ static void s3c24xx_rtc_disable(struct s3c_rtc *info)
con = readb(info->base + S3C2410_TICNT);
con &= ~S3C2410_TICNT_ENABLE;
writeb(con, info->base + S3C2410_TICNT);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
}
static void s3c6410_rtc_disable(struct s3c_rtc *info)
{
unsigned int con;
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
con = readw(info->base + S3C2410_RTCCON);
con &= ~S3C64XX_RTCCON_TICEN;
con &= ~S3C2410_RTCCON_RTCEN;
writew(con, info->base + S3C2410_RTCCON);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
}
static int s3c_rtc_remove(struct platform_device *pdev)
@ -554,6 +496,20 @@ static int s3c_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
/* Check RTC Time */
if (s3c_rtc_gettime(&pdev->dev, &rtc_tm)) {
rtc_tm.tm_year = 100;
rtc_tm.tm_mon = 0;
rtc_tm.tm_mday = 1;
rtc_tm.tm_hour = 0;
rtc_tm.tm_min = 0;
rtc_tm.tm_sec = 0;
s3c_rtc_settime(&pdev->dev, &rtc_tm);
dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
}
/* register RTC and exit */
info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops,
THIS_MODULE);
@ -577,36 +533,21 @@ static int s3c_rtc_probe(struct platform_device *pdev)
goto err_nortc;
}
/* Check RTC Time */
s3c_rtc_gettime(&pdev->dev, &rtc_tm);
if (rtc_valid_tm(&rtc_tm)) {
rtc_tm.tm_year = 100;
rtc_tm.tm_mon = 0;
rtc_tm.tm_mday = 1;
rtc_tm.tm_hour = 0;
rtc_tm.tm_min = 0;
rtc_tm.tm_sec = 0;
s3c_rtc_settime(&pdev->dev, &rtc_tm);
dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
}
if (info->data->select_tick_clk)
info->data->select_tick_clk(info);
s3c_rtc_setfreq(info, 1);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
s3c_rtc_disable_clk(info);
return 0;
err_nortc:
if (info->data->disable)
info->data->disable(info);
if (info->data->needs_src_clk)
clk_disable_unprepare(info->rtc_src_clk);
clk_disable_unprepare(info->rtc_clk);
return ret;
@ -618,9 +559,7 @@ static int s3c_rtc_suspend(struct device *dev)
{
struct s3c_rtc *info = dev_get_drvdata(dev);
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
s3c_rtc_enable_clk(info);
/* save TICNT for anyone using periodic interrupts */
if (info->data->save_tick_cnt)
@ -636,10 +575,6 @@ static int s3c_rtc_suspend(struct device *dev)
dev_err(dev, "enable_irq_wake failed\n");
}
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
return 0;
}
@ -647,25 +582,19 @@ static int s3c_rtc_resume(struct device *dev)
{
struct s3c_rtc *info = dev_get_drvdata(dev);
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
if (info->data->enable)
info->data->enable(info);
if (info->data->restore_tick_cnt)
info->data->restore_tick_cnt(info);
s3c_rtc_disable_clk(info);
if (device_may_wakeup(dev) && info->wake_en) {
disable_irq_wake(info->irq_alarm);
info->wake_en = false;
}
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
return 0;
}
#endif
@ -673,29 +602,13 @@ static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume);
static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask)
{
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
s3c_rtc_alarm_clk_enable(info, false);
}
static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask)
{
clk_enable(info->rtc_clk);
if (info->data->needs_src_clk)
clk_enable(info->rtc_src_clk);
rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF);
writeb(mask, info->base + S3C2410_INTP);
if (info->data->needs_src_clk)
clk_disable(info->rtc_src_clk);
clk_disable(info->rtc_clk);
s3c_rtc_alarm_clk_enable(info, false);
}
static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq)

View File

@ -15,6 +15,8 @@
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/bcd.h>
@ -90,7 +92,7 @@ struct s5m_rtc_info {
struct regmap *regmap;
struct rtc_device *rtc_dev;
int irq;
int device_type;
enum sec_device_type device_type;
int rtc_24hr_mode;
const struct s5m_rtc_reg_config *regs;
};
@ -146,7 +148,7 @@ static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data)
data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
if (tm->tm_year < 100) {
pr_err("s5m8767 RTC cannot handle the year %d.\n",
pr_err("RTC cannot handle the year %d\n",
1900 + tm->tm_year);
return -EINVAL;
} else {
@ -187,6 +189,7 @@ static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info,
val &= S5M_ALARM0_STATUS;
break;
case S2MPS14X:
case S2MPS13X:
ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2,
&val);
val &= S2MPS_ALARM0_STATUS;
@ -252,6 +255,9 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
case S2MPS14X:
data |= S2MPS_RTC_RUDR_MASK;
break;
case S2MPS13X:
data |= S2MPS13_RTC_AUDR_MASK;
break;
default:
return -EINVAL;
}
@ -265,6 +271,11 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
ret = s5m8767_wait_for_udr_update(info);
/* On S2MPS13 the AUDR is not auto-cleared */
if (info->device_type == S2MPS13X)
regmap_update_bits(info->regmap, info->regs->rtc_udr_update,
S2MPS13_RTC_AUDR_MASK, 0);
return ret;
}
@ -306,7 +317,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
u8 data[info->regs->regs_count];
int ret;
if (info->device_type == S2MPS14X) {
if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) {
ret = regmap_update_bits(info->regmap,
info->regs->rtc_udr_update,
S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK);
@ -329,6 +340,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
case S5M8767X:
case S2MPS14X:
case S2MPS13X:
s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
break;
@ -355,6 +367,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
break;
case S5M8767X:
case S2MPS14X:
case S2MPS13X:
ret = s5m8767_tm_to_data(tm, data);
break;
default:
@ -402,6 +415,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
case S5M8767X:
case S2MPS14X:
case S2MPS13X:
s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
alrm->enabled = 0;
for (i = 0; i < info->regs->regs_count; i++) {
@ -450,6 +464,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
case S5M8767X:
case S2MPS14X:
case S2MPS13X:
for (i = 0; i < info->regs->regs_count; i++)
data[i] &= ~ALARM_ENABLE_MASK;
@ -494,6 +509,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
case S5M8767X:
case S2MPS14X:
case S2MPS13X:
data[RTC_SEC] |= ALARM_ENABLE_MASK;
data[RTC_MIN] |= ALARM_ENABLE_MASK;
data[RTC_HOUR] |= ALARM_ENABLE_MASK;
@ -533,6 +549,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
case S5M8767X:
case S2MPS14X:
case S2MPS13X:
s5m8767_tm_to_data(&alrm->time, data);
break;
@ -615,6 +632,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
break;
case S2MPS14X:
case S2MPS13X:
data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
ret = regmap_write(info->regmap, info->regs->ctrl, data[0]);
break;
@ -650,8 +668,9 @@ static int s5m_rtc_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
switch (pdata->device_type) {
switch (platform_get_device_id(pdev)->driver_data) {
case S2MPS14X:
case S2MPS13X:
regmap_cfg = &s2mps14_rtc_regmap_config;
info->regs = &s2mps_rtc_regs;
alarm_irq = S2MPS14_IRQ_RTCA0;
@ -667,7 +686,9 @@ static int s5m_rtc_probe(struct platform_device *pdev)
alarm_irq = S5M8767_IRQ_RTCA1;
break;
default:
dev_err(&pdev->dev, "Device type is not supported by RTC driver\n");
dev_err(&pdev->dev,
"Device type %lu is not supported by RTC driver\n",
platform_get_device_id(pdev)->driver_data);
return -ENODEV;
}
@ -687,7 +708,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
info->dev = &pdev->dev;
info->s5m87xx = s5m87xx;
info->device_type = s5m87xx->device_type;
info->device_type = platform_get_device_id(pdev)->driver_data;
if (s5m87xx->irq_data) {
info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq);
@ -772,6 +793,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);
static const struct platform_device_id s5m_rtc_id[] = {
{ "s5m-rtc", S5M8767X },
{ "s2mps13-rtc", S2MPS13X },
{ "s2mps14-rtc", S2MPS14X },
{ },
};

View File

@ -42,6 +42,8 @@
#define STMP3XXX_RTC_STAT 0x10
#define STMP3XXX_RTC_STAT_STALE_SHIFT 16
#define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000
#define STMP3XXX_RTC_STAT_XTAL32000_PRESENT 0x10000000
#define STMP3XXX_RTC_STAT_XTAL32768_PRESENT 0x08000000
#define STMP3XXX_RTC_SECONDS 0x30
@ -52,9 +54,13 @@
#define STMP3XXX_RTC_PERSISTENT0 0x60
#define STMP3XXX_RTC_PERSISTENT0_SET 0x64
#define STMP3XXX_RTC_PERSISTENT0_CLR 0x68
#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002
#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004
#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080
#define STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE (1 << 0)
#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN (1 << 1)
#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN (1 << 2)
#define STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP (1 << 4)
#define STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP (1 << 5)
#define STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ (1 << 6)
#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE (1 << 7)
#define STMP3XXX_RTC_PERSISTENT1 0x70
/* missing bitmask in headers */
@ -248,6 +254,9 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
{
struct stmp3xxx_rtc_data *rtc_data;
struct resource *r;
u32 rtc_stat;
u32 pers0_set, pers0_clr;
u32 crystalfreq = 0;
int err;
rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL);
@ -268,8 +277,8 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
rtc_data->irq_alarm = platform_get_irq(pdev, 0);
if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) &
STMP3XXX_RTC_STAT_RTC_PRESENT)) {
rtc_stat = readl(rtc_data->io + STMP3XXX_RTC_STAT);
if (!(rtc_stat & STMP3XXX_RTC_STAT_RTC_PRESENT)) {
dev_err(&pdev->dev, "no device onboard\n");
return -ENODEV;
}
@ -282,9 +291,54 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
return err;
}
/*
* Obviously the rtc needs a clock input to be able to run.
* This clock can be provided by an external 32k crystal. If that one is
* missing XTAL must not be disabled in suspend which consumes a
* lot of power. Normally the presence and exact frequency (supported
* are 32000 Hz and 32768 Hz) is detectable from fuses, but as reality
* proves these fuses are not blown correctly on all machines, so the
* frequency can be overridden in the device tree.
*/
if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32000_PRESENT)
crystalfreq = 32000;
else if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32768_PRESENT)
crystalfreq = 32768;
of_property_read_u32(pdev->dev.of_node, "stmp,crystal-freq",
&crystalfreq);
switch (crystalfreq) {
case 32000:
/* keep 32kHz crystal running in low-power mode */
pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ |
STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP;
break;
case 32768:
/* keep 32.768kHz crystal running in low-power mode */
pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP |
STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ;
break;
default:
dev_warn(&pdev->dev,
"invalid crystal-freq specified in device-tree. Assuming no crystal\n");
/* fall-through */
case 0:
/* keep XTAL on in low-power mode */
pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP;
pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP |
STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE;
}
writel(pers0_set, rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET);
writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE | pers0_clr,
rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR);
writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN |

View File

@ -18,6 +18,8 @@
* 2 of the License, or (at your option) any later version.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
@ -145,8 +147,7 @@ static int twl_rtc_read_u8(u8 *data, u8 reg)
ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg]));
if (ret < 0)
pr_err("twl_rtc: Could not read TWL"
"register %X - error %d\n", reg, ret);
pr_err("Could not read TWL register %X - error %d\n", reg, ret);
return ret;
}
@ -159,8 +160,8 @@ static int twl_rtc_write_u8(u8 data, u8 reg)
ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg]));
if (ret < 0)
pr_err("twl_rtc: Could not write TWL"
"register %X - error %d\n", reg, ret);
pr_err("Could not write TWL register %X - error %d\n",
reg, ret);
return ret;
}

View File

@ -22,6 +22,7 @@
#include <linux/rtc.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/bitops.h>
#define DRV_VERSION "1.0.8"
@ -366,8 +367,7 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim)
* perform sign extension. The formula is
* Catr = (atr * 0.25pF) + 11.00pF.
*/
if (atr & 0x20)
atr |= 0xC0;
atr = sign_extend32(atr, 5);
dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __func__, atr, atr);

View File

@ -1079,22 +1079,18 @@ bfad_start_ops(struct bfad_s *bfad) {
int
bfad_worker(void *ptr)
{
struct bfad_s *bfad;
unsigned long flags;
struct bfad_s *bfad = ptr;
unsigned long flags;
bfad = (struct bfad_s *)ptr;
if (kthread_should_stop())
return 0;
while (!kthread_should_stop()) {
/* Send event BFAD_E_INIT_SUCCESS */
bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS);
/* Send event BFAD_E_INIT_SUCCESS */
bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS);
spin_lock_irqsave(&bfad->bfad_lock, flags);
bfad->bfad_tsk = NULL;
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
break;
}
spin_lock_irqsave(&bfad->bfad_lock, flags);
bfad->bfad_tsk = NULL;
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
return 0;
}

View File

@ -86,6 +86,7 @@ int main(int argc, char **argv)
case 'j':
include_jump = 1;
break;
default:
return usage();
}
}

View File

@ -61,6 +61,7 @@ adfs_fplus_read(struct super_block *sb, unsigned int id, unsigned int sz, struct
kcalloc(size, sizeof(struct buffer_head *),
GFP_KERNEL);
if (!bh_fplus) {
ret = -ENOMEM;
adfs_error(sb, "not enough memory for"
" dir object %X (%d blocks)", id, size);
goto out;

View File

@ -316,7 +316,7 @@ static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_di
dm = kmalloc(nzones * sizeof(*dm), GFP_KERNEL);
if (dm == NULL) {
adfs_error(sb, "not enough memory");
return NULL;
return ERR_PTR(-ENOMEM);
}
for (zone = 0; zone < nzones; zone++, map_addr++) {
@ -349,7 +349,7 @@ static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_di
brelse(dm[zone].dm_bh);
kfree(dm);
return NULL;
return ERR_PTR(-EIO);
}
static inline unsigned long adfs_discsize(struct adfs_discrecord *dr, int block_bits)
@ -370,6 +370,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
unsigned char *b_data;
struct adfs_sb_info *asb;
struct inode *root;
int ret = -EINVAL;
sb->s_flags |= MS_NODIRATIME;
@ -391,6 +392,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
sb_set_blocksize(sb, BLOCK_SIZE);
if (!(bh = sb_bread(sb, ADFS_DISCRECORD / BLOCK_SIZE))) {
adfs_error(sb, "unable to read superblock");
ret = -EIO;
goto error;
}
@ -400,6 +402,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
if (!silent)
printk("VFS: Can't find an adfs filesystem on dev "
"%s.\n", sb->s_id);
ret = -EINVAL;
goto error_free_bh;
}
@ -412,6 +415,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
if (!silent)
printk("VPS: Can't find an adfs filesystem on dev "
"%s.\n", sb->s_id);
ret = -EINVAL;
goto error_free_bh;
}
@ -421,11 +425,13 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
if (!bh) {
adfs_error(sb, "couldn't read superblock on "
"2nd try.");
ret = -EIO;
goto error;
}
b_data = bh->b_data + (ADFS_DISCRECORD % sb->s_blocksize);
if (adfs_checkbblk(b_data)) {
adfs_error(sb, "disc record mismatch, very weird!");
ret = -EINVAL;
goto error_free_bh;
}
dr = (struct adfs_discrecord *)(b_data + ADFS_DR_OFFSET);
@ -433,6 +439,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
if (!silent)
printk(KERN_ERR "VFS: Unsupported blocksize on dev "
"%s.\n", sb->s_id);
ret = -EINVAL;
goto error;
}
@ -447,10 +454,12 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
asb->s_size = adfs_discsize(dr, sb->s_blocksize_bits);
asb->s_version = dr->format_version;
asb->s_log2sharesize = dr->log2sharesize;
asb->s_map = adfs_read_map(sb, dr);
if (!asb->s_map)
if (IS_ERR(asb->s_map)) {
ret = PTR_ERR(asb->s_map);
goto error_free_bh;
}
brelse(bh);
@ -499,6 +508,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
brelse(asb->s_map[i].dm_bh);
kfree(asb->s_map);
adfs_error(sb, "get root inode failed\n");
ret = -EIO;
goto error;
}
return 0;
@ -508,7 +518,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
error:
sb->s_fs_info = NULL;
kfree(asb);
return -EINVAL;
return ret;
}
static struct dentry *adfs_mount(struct file_system_type *fs_type,

View File

@ -106,18 +106,22 @@ struct affs_sb_info {
spinlock_t work_lock; /* protects sb_work and work_queued */
};
#define SF_INTL 0x0001 /* International filesystem. */
#define SF_BM_VALID 0x0002 /* Bitmap is valid. */
#define SF_IMMUTABLE 0x0004 /* Protection bits cannot be changed */
#define SF_QUIET 0x0008 /* chmod errors will be not reported */
#define SF_SETUID 0x0010 /* Ignore Amiga uid */
#define SF_SETGID 0x0020 /* Ignore Amiga gid */
#define SF_SETMODE 0x0040 /* Ignore Amiga protection bits */
#define SF_MUFS 0x0100 /* Use MUFS uid/gid mapping */
#define SF_OFS 0x0200 /* Old filesystem */
#define SF_PREFIX 0x0400 /* Buffer for prefix is allocated */
#define SF_VERBOSE 0x0800 /* Talk about fs when mounting */
#define SF_NO_TRUNCATE 0x1000 /* Don't truncate filenames */
#define AFFS_MOUNT_SF_INTL 0x0001 /* International filesystem. */
#define AFFS_MOUNT_SF_BM_VALID 0x0002 /* Bitmap is valid. */
#define AFFS_MOUNT_SF_IMMUTABLE 0x0004 /* Protection bits cannot be changed */
#define AFFS_MOUNT_SF_QUIET 0x0008 /* chmod errors will be not reported */
#define AFFS_MOUNT_SF_SETUID 0x0010 /* Ignore Amiga uid */
#define AFFS_MOUNT_SF_SETGID 0x0020 /* Ignore Amiga gid */
#define AFFS_MOUNT_SF_SETMODE 0x0040 /* Ignore Amiga protection bits */
#define AFFS_MOUNT_SF_MUFS 0x0100 /* Use MUFS uid/gid mapping */
#define AFFS_MOUNT_SF_OFS 0x0200 /* Old filesystem */
#define AFFS_MOUNT_SF_PREFIX 0x0400 /* Buffer for prefix is allocated */
#define AFFS_MOUNT_SF_VERBOSE 0x0800 /* Talk about fs when mounting */
#define AFFS_MOUNT_SF_NO_TRUNCATE 0x1000 /* Don't truncate filenames */
#define affs_clear_opt(o, opt) (o &= ~AFFS_MOUNT_##opt)
#define affs_set_opt(o, opt) (o |= AFFS_MOUNT_##opt)
#define affs_test_opt(o, opt) ((o) & AFFS_MOUNT_##opt)
/* short cut to get to the affs specific sb data */
static inline struct affs_sb_info *AFFS_SB(struct super_block *sb)

View File

@ -472,7 +472,8 @@ bool
affs_nofilenametruncate(const struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
return AFFS_SB(inode->i_sb)->s_flags & SF_NO_TRUNCATE;
return affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_NO_TRUNCATE);
}

View File

@ -914,7 +914,7 @@ affs_truncate(struct inode *inode)
if (inode->i_size) {
AFFS_I(inode)->i_blkcnt = last_blk + 1;
AFFS_I(inode)->i_extcnt = ext + 1;
if (AFFS_SB(sb)->s_flags & SF_OFS) {
if (affs_test_opt(AFFS_SB(sb)->s_flags, SF_OFS)) {
struct buffer_head *bh = affs_bread_ino(inode, last_blk, 0);
u32 tmp;
if (IS_ERR(bh)) {

View File

@ -66,23 +66,23 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
AFFS_I(inode)->i_lastalloc = 0;
AFFS_I(inode)->i_pa_cnt = 0;
if (sbi->s_flags & SF_SETMODE)
if (affs_test_opt(sbi->s_flags, SF_SETMODE))
inode->i_mode = sbi->s_mode;
else
inode->i_mode = prot_to_mode(prot);
id = be16_to_cpu(tail->uid);
if (id == 0 || sbi->s_flags & SF_SETUID)
if (id == 0 || affs_test_opt(sbi->s_flags, SF_SETUID))
inode->i_uid = sbi->s_uid;
else if (id == 0xFFFF && sbi->s_flags & SF_MUFS)
else if (id == 0xFFFF && affs_test_opt(sbi->s_flags, SF_MUFS))
i_uid_write(inode, 0);
else
i_uid_write(inode, id);
id = be16_to_cpu(tail->gid);
if (id == 0 || sbi->s_flags & SF_SETGID)
if (id == 0 || affs_test_opt(sbi->s_flags, SF_SETGID))
inode->i_gid = sbi->s_gid;
else if (id == 0xFFFF && sbi->s_flags & SF_MUFS)
else if (id == 0xFFFF && affs_test_opt(sbi->s_flags, SF_MUFS))
i_gid_write(inode, 0);
else
i_gid_write(inode, id);
@ -94,7 +94,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
/* fall through */
case ST_USERDIR:
if (be32_to_cpu(tail->stype) == ST_USERDIR ||
sbi->s_flags & SF_SETMODE) {
affs_test_opt(sbi->s_flags, SF_SETMODE)) {
if (inode->i_mode & S_IRUSR)
inode->i_mode |= S_IXUSR;
if (inode->i_mode & S_IRGRP)
@ -133,7 +133,8 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
}
if (tail->link_chain)
set_nlink(inode, 2);
inode->i_mapping->a_ops = (sbi->s_flags & SF_OFS) ? &affs_aops_ofs : &affs_aops;
inode->i_mapping->a_ops = affs_test_opt(sbi->s_flags, SF_OFS) ?
&affs_aops_ofs : &affs_aops;
inode->i_op = &affs_file_inode_operations;
inode->i_fop = &affs_file_operations;
break;
@ -190,15 +191,15 @@ affs_write_inode(struct inode *inode, struct writeback_control *wbc)
if (!(inode->i_ino == AFFS_SB(sb)->s_root_block)) {
uid = i_uid_read(inode);
gid = i_gid_read(inode);
if (AFFS_SB(sb)->s_flags & SF_MUFS) {
if (affs_test_opt(AFFS_SB(sb)->s_flags, SF_MUFS)) {
if (uid == 0 || uid == 0xFFFF)
uid = uid ^ ~0;
if (gid == 0 || gid == 0xFFFF)
gid = gid ^ ~0;
}
if (!(AFFS_SB(sb)->s_flags & SF_SETUID))
if (!affs_test_opt(AFFS_SB(sb)->s_flags, SF_SETUID))
tail->uid = cpu_to_be16(uid);
if (!(AFFS_SB(sb)->s_flags & SF_SETGID))
if (!affs_test_opt(AFFS_SB(sb)->s_flags, SF_SETGID))
tail->gid = cpu_to_be16(gid);
}
}
@ -221,11 +222,14 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
if (error)
goto out;
if (((attr->ia_valid & ATTR_UID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETUID)) ||
((attr->ia_valid & ATTR_GID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETGID)) ||
if (((attr->ia_valid & ATTR_UID) &&
affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_SETUID)) ||
((attr->ia_valid & ATTR_GID) &&
affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_SETGID)) ||
((attr->ia_valid & ATTR_MODE) &&
(AFFS_SB(inode->i_sb)->s_flags & (SF_SETMODE | SF_IMMUTABLE)))) {
if (!(AFFS_SB(inode->i_sb)->s_flags & SF_QUIET))
(AFFS_SB(inode->i_sb)->s_flags &
(AFFS_MOUNT_SF_SETMODE | AFFS_MOUNT_SF_IMMUTABLE)))) {
if (!affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_QUIET))
error = -EPERM;
goto out;
}

View File

@ -53,7 +53,8 @@ affs_intl_toupper(int ch)
static inline toupper_t
affs_get_toupper(struct super_block *sb)
{
return AFFS_SB(sb)->s_flags & SF_INTL ? affs_intl_toupper : affs_toupper;
return affs_test_opt(AFFS_SB(sb)->s_flags, SF_INTL) ?
affs_intl_toupper : affs_toupper;
}
/*
@ -275,7 +276,8 @@ affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
inode->i_op = &affs_file_inode_operations;
inode->i_fop = &affs_file_operations;
inode->i_mapping->a_ops = (AFFS_SB(sb)->s_flags & SF_OFS) ? &affs_aops_ofs : &affs_aops;
inode->i_mapping->a_ops = affs_test_opt(AFFS_SB(sb)->s_flags, SF_OFS) ?
&affs_aops_ofs : &affs_aops;
error = affs_add_entry(dir, inode, dentry, ST_FILE);
if (error) {
clear_nlink(inode);

View File

@ -227,22 +227,22 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved,
if (match_octal(&args[0], &option))
return 0;
*mode = option & 0777;
*mount_opts |= SF_SETMODE;
affs_set_opt(*mount_opts, SF_SETMODE);
break;
case Opt_mufs:
*mount_opts |= SF_MUFS;
affs_set_opt(*mount_opts, SF_MUFS);
break;
case Opt_notruncate:
*mount_opts |= SF_NO_TRUNCATE;
affs_set_opt(*mount_opts, SF_NO_TRUNCATE);
break;
case Opt_prefix:
*prefix = match_strdup(&args[0]);
if (!*prefix)
return 0;
*mount_opts |= SF_PREFIX;
affs_set_opt(*mount_opts, SF_PREFIX);
break;
case Opt_protect:
*mount_opts |= SF_IMMUTABLE;
affs_set_opt(*mount_opts, SF_IMMUTABLE);
break;
case Opt_reserved:
if (match_int(&args[0], reserved))
@ -258,7 +258,7 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved,
*gid = make_kgid(current_user_ns(), option);
if (!gid_valid(*gid))
return 0;
*mount_opts |= SF_SETGID;
affs_set_opt(*mount_opts, SF_SETGID);
break;
case Opt_setuid:
if (match_int(&args[0], &option))
@ -266,10 +266,10 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved,
*uid = make_kuid(current_user_ns(), option);
if (!uid_valid(*uid))
return 0;
*mount_opts |= SF_SETUID;
affs_set_opt(*mount_opts, SF_SETUID);
break;
case Opt_verbose:
*mount_opts |= SF_VERBOSE;
affs_set_opt(*mount_opts, SF_VERBOSE);
break;
case Opt_volume: {
char *vol = match_strdup(&args[0]);
@ -435,30 +435,31 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
case MUFS_FS:
case MUFS_INTLFFS:
case MUFS_DCFFS:
sbi->s_flags |= SF_MUFS;
affs_set_opt(sbi->s_flags, SF_MUFS);
/* fall thru */
case FS_INTLFFS:
case FS_DCFFS:
sbi->s_flags |= SF_INTL;
affs_set_opt(sbi->s_flags, SF_INTL);
break;
case MUFS_FFS:
sbi->s_flags |= SF_MUFS;
affs_set_opt(sbi->s_flags, SF_MUFS);
break;
case FS_FFS:
break;
case MUFS_OFS:
sbi->s_flags |= SF_MUFS;
affs_set_opt(sbi->s_flags, SF_MUFS);
/* fall thru */
case FS_OFS:
sbi->s_flags |= SF_OFS;
affs_set_opt(sbi->s_flags, SF_OFS);
sb->s_flags |= MS_NOEXEC;
break;
case MUFS_DCOFS:
case MUFS_INTLOFS:
sbi->s_flags |= SF_MUFS;
affs_set_opt(sbi->s_flags, SF_MUFS);
case FS_DCOFS:
case FS_INTLOFS:
sbi->s_flags |= SF_INTL | SF_OFS;
affs_set_opt(sbi->s_flags, SF_INTL);
affs_set_opt(sbi->s_flags, SF_OFS);
sb->s_flags |= MS_NOEXEC;
break;
default:
@ -467,7 +468,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
return -EINVAL;
}
if (mount_flags & SF_VERBOSE) {
if (affs_test_opt(mount_flags, SF_VERBOSE)) {
u8 len = AFFS_ROOT_TAIL(sb, root_bh)->disk_name[0];
pr_notice("Mounting volume \"%.*s\": Type=%.3s\\%c, Blocksize=%d\n",
len > 31 ? 31 : len,
@ -478,7 +479,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_flags |= MS_NODEV | MS_NOSUID;
sbi->s_data_blksize = sb->s_blocksize;
if (sbi->s_flags & SF_OFS)
if (affs_test_opt(sbi->s_flags, SF_OFS))
sbi->s_data_blksize -= 24;
tmp_flags = sb->s_flags;
@ -493,7 +494,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
if (IS_ERR(root_inode))
return PTR_ERR(root_inode);
if (AFFS_SB(sb)->s_flags & SF_INTL)
if (affs_test_opt(AFFS_SB(sb)->s_flags, SF_INTL))
sb->s_d_op = &affs_intl_dentry_operations;
else
sb->s_d_op = &affs_dentry_operations;
@ -520,10 +521,14 @@ affs_remount(struct super_block *sb, int *flags, char *data)
int root_block;
unsigned long mount_flags;
int res = 0;
char *new_opts = kstrdup(data, GFP_KERNEL);
char *new_opts;
char volume[32];
char *prefix = NULL;
new_opts = kstrdup(data, GFP_KERNEL);
if (!new_opts)
return -ENOMEM;
pr_debug("%s(flags=0x%x,opts=\"%s\")\n", __func__, *flags, data);
sync_filesystem(sb);

View File

@ -19,16 +19,16 @@ typedef u64 befs_blocknr_t;
* BeFS in memory structures
*/
typedef struct befs_mount_options {
struct befs_mount_options {
kgid_t gid;
kuid_t uid;
int use_gid;
int use_uid;
int debug;
char *iocharset;
} befs_mount_options;
};
typedef struct befs_sb_info {
struct befs_sb_info {
u32 magic1;
u32 block_size;
u32 block_shift;
@ -52,12 +52,11 @@ typedef struct befs_sb_info {
befs_inode_addr indices;
u32 magic3;
befs_mount_options mount_opts;
struct befs_mount_options mount_opts;
struct nls_table *nls;
};
} befs_sb_info;
typedef struct befs_inode_info {
struct befs_inode_info {
u32 i_flags;
u32 i_type;
@ -71,8 +70,7 @@ typedef struct befs_inode_info {
} i_data;
struct inode vfs_inode;
} befs_inode_info;
};
enum befs_err {
BEFS_OK,
@ -105,13 +103,13 @@ void befs_dump_index_node(const struct super_block *sb, befs_btree_nodehead *);
/* Gets a pointer to the private portion of the super_block
* structure from the public part
*/
static inline befs_sb_info *
static inline struct befs_sb_info *
BEFS_SB(const struct super_block *super)
{
return (befs_sb_info *) super->s_fs_info;
return (struct befs_sb_info *) super->s_fs_info;
}
static inline befs_inode_info *
static inline struct befs_inode_info *
BEFS_I(const struct inode *inode)
{
return list_entry(inode, struct befs_inode_info, vfs_inode);

View File

@ -168,7 +168,7 @@ befs_count_blocks(struct super_block * sb, befs_data_stream * ds)
befs_blocknr_t blocks;
befs_blocknr_t datablocks; /* File data blocks */
befs_blocknr_t metablocks; /* FS metadata blocks */
befs_sb_info *befs_sb = BEFS_SB(sb);
struct befs_sb_info *befs_sb = BEFS_SB(sb);
befs_debug(sb, "---> %s", __func__);
@ -428,7 +428,7 @@ befs_find_brun_dblindirect(struct super_block *sb,
struct buffer_head *indir_block;
befs_block_run indir_run;
befs_disk_inode_addr *iaddr_array = NULL;
befs_sb_info *befs_sb = BEFS_SB(sb);
struct befs_sb_info *befs_sb = BEFS_SB(sb);
befs_blocknr_t indir_start_blk =
data->max_indirect_range >> befs_sb->block_shift;

View File

@ -28,7 +28,7 @@ befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr)
{
struct buffer_head *bh = NULL;
befs_blocknr_t block = 0;
befs_sb_info *befs_sb = BEFS_SB(sb);
struct befs_sb_info *befs_sb = BEFS_SB(sb);
befs_debug(sb, "---> Enter %s "
"[%u, %hu, %hu]", __func__, iaddr.allocation_group,

View File

@ -51,7 +51,7 @@ static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
static void befs_put_super(struct super_block *);
static int befs_remount(struct super_block *, int *, char *);
static int befs_statfs(struct dentry *, struct kstatfs *);
static int parse_options(char *, befs_mount_options *);
static int parse_options(char *, struct befs_mount_options *);
static const struct super_operations befs_sops = {
.alloc_inode = befs_alloc_inode, /* allocate a new inode */
@ -304,9 +304,8 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
{
struct buffer_head *bh = NULL;
befs_inode *raw_inode = NULL;
befs_sb_info *befs_sb = BEFS_SB(sb);
befs_inode_info *befs_ino = NULL;
struct befs_sb_info *befs_sb = BEFS_SB(sb);
struct befs_inode_info *befs_ino = NULL;
struct inode *inode;
long ret = -EIO;
@ -472,7 +471,7 @@ static void *
befs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct super_block *sb = dentry->d_sb;
befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
struct befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
befs_data_stream *data = &befs_ino->i_data.ds;
befs_off_t len = data->size;
char *link;
@ -502,7 +501,8 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd)
static void *
befs_fast_follow_link(struct dentry *dentry, struct nameidata *nd)
{
befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
struct befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
nd_set_link(nd, befs_ino->i_data.symlink);
return NULL;
}
@ -669,7 +669,7 @@ static const match_table_t befs_tokens = {
};
static int
parse_options(char *options, befs_mount_options * opts)
parse_options(char *options, struct befs_mount_options *opts)
{
char *p;
substring_t args[MAX_OPT_ARGS];
@ -769,7 +769,7 @@ static int
befs_fill_super(struct super_block *sb, void *data, int silent)
{
struct buffer_head *bh;
befs_sb_info *befs_sb;
struct befs_sb_info *befs_sb;
befs_super_block *disk_sb;
struct inode *root;
long ret = -EINVAL;

View File

@ -24,7 +24,7 @@
int
befs_load_sb(struct super_block *sb, befs_super_block * disk_sb)
{
befs_sb_info *befs_sb = BEFS_SB(sb);
struct befs_sb_info *befs_sb = BEFS_SB(sb);
/* Check the byte order of the filesystem */
if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE)
@ -59,7 +59,7 @@ befs_load_sb(struct super_block *sb, befs_super_block * disk_sb)
int
befs_check_sb(struct super_block *sb)
{
befs_sb_info *befs_sb = BEFS_SB(sb);
struct befs_sb_info *befs_sb = BEFS_SB(sb);
/* Check magic headers of super block */
if ((befs_sb->magic1 != BEFS_SUPER_MAGIC1)

View File

@ -86,7 +86,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
inode = new_inode(s);
if (!inode)
return -ENOSPC;
return -ENOMEM;
mutex_lock(&info->bfs_lock);
ino = find_first_zero_bit(info->si_imap, info->si_lasti + 1);
if (ino > info->si_lasti) {
@ -293,7 +293,7 @@ static int bfs_add_entry(struct inode *dir, const unsigned char *name,
for (block = sblock; block <= eblock; block++) {
bh = sb_bread(dir->i_sb, block);
if (!bh)
return -ENOSPC;
return -EIO;
for (off = 0; off < BFS_BSIZE; off += BFS_DIRENT_SIZE) {
de = (struct bfs_dirent *)(bh->b_data + off);
if (!de->ino) {

View File

@ -9,6 +9,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
@ -521,9 +522,8 @@ static int parse_command(const char __user *buffer, size_t count)
static void entry_status(Node *e, char *page)
{
char *dp;
char *status = "disabled";
const char *flags = "flags: ";
char *dp = page;
const char *status = "disabled";
if (test_bit(Enabled, &e->flags))
status = "enabled";
@ -533,12 +533,10 @@ static void entry_status(Node *e, char *page)
return;
}
sprintf(page, "%s\ninterpreter %s\n", status, e->interpreter);
dp = page + strlen(page);
dp += sprintf(dp, "%s\ninterpreter %s\n", status, e->interpreter);
/* print the special flags */
sprintf(dp, "%s", flags);
dp += strlen(flags);
dp += sprintf(dp, "flags: ");
if (e->flags & MISC_FMT_PRESERVE_ARGV0)
*dp++ = 'P';
if (e->flags & MISC_FMT_OPEN_BINARY)
@ -550,21 +548,11 @@ static void entry_status(Node *e, char *page)
if (!test_bit(Magic, &e->flags)) {
sprintf(dp, "extension .%s\n", e->magic);
} else {
int i;
sprintf(dp, "offset %i\nmagic ", e->offset);
dp = page + strlen(page);
for (i = 0; i < e->size; i++) {
sprintf(dp, "%02x", 0xff & (int) (e->magic[i]));
dp += 2;
}
dp += sprintf(dp, "offset %i\nmagic ", e->offset);
dp = bin2hex(dp, e->magic, e->size);
if (e->mask) {
sprintf(dp, "\nmask ");
dp += 6;
for (i = 0; i < e->size; i++) {
sprintf(dp, "%02x", 0xff & (int) (e->mask[i]));
dp += 2;
}
dp += sprintf(dp, "\nmask ");
dp = bin2hex(dp, e->mask, e->size);
}
*dp++ = '\n';
*dp = '\0';

View File

@ -926,10 +926,14 @@ static int de_thread(struct task_struct *tsk)
if (!thread_group_leader(tsk)) {
struct task_struct *leader = tsk->group_leader;
sig->notify_count = -1; /* for exit_notify() */
for (;;) {
threadgroup_change_begin(tsk);
write_lock_irq(&tasklist_lock);
/*
* Do this under tasklist_lock to ensure that
* exit_notify() can't miss ->group_exit_task
*/
sig->notify_count = -1;
if (likely(leader->exit_state))
break;
__set_current_state(TASK_KILLABLE);
@ -1078,7 +1082,13 @@ int flush_old_exec(struct linux_binprm * bprm)
if (retval)
goto out;
/*
* Must be called _before_ exec_mmap() as bprm->mm is
* not visibile until then. This also enables the update
* to be lockless.
*/
set_mm_exe_file(bprm->mm, bprm->file);
/*
* Release all of the old mmap stuff
*/

View File

@ -8,9 +8,7 @@
* May 1999. AV. Fixed the bogosity with FAT32 (read "FAT28"). Fscking lusers.
*/
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/buffer_head.h>
#include "fat.h"
/* this must be > 0. */

View File

@ -13,13 +13,9 @@
* Short name translation 1999, 2001 by Wolfram Pienkoss <wp@bszh.de>
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/buffer_head.h>
#include <linux/compat.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include "fat.h"
/*

View File

@ -2,11 +2,8 @@
#define _FAT_H
#include <linux/buffer_head.h>
#include <linux/string.h>
#include <linux/nls.h>
#include <linux/fs.h>
#include <linux/hash.h>
#include <linux/mutex.h>
#include <linux/ratelimit.h>
#include <linux/msdos_fs.h>
@ -66,7 +63,7 @@ struct msdos_sb_info {
unsigned short sec_per_clus; /* sectors/cluster */
unsigned short cluster_bits; /* log2(cluster_size) */
unsigned int cluster_size; /* cluster size */
unsigned char fats, fat_bits; /* number of FATs, FAT bits (12 or 16) */
unsigned char fats, fat_bits; /* number of FATs, FAT bits (12,16 or 32) */
unsigned short fat_start;
unsigned long fat_length; /* FAT start & length (sec.) */
unsigned long dir_start;

View File

@ -3,9 +3,6 @@
* Released under GPL v2.
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/msdos_fs.h>
#include <linux/blkdev.h>
#include "fat.h"

View File

@ -10,10 +10,6 @@
#include <linux/module.h>
#include <linux/compat.h>
#include <linux/mount.h>
#include <linux/time.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
#include <linux/backing-dev.h>
#include <linux/blkdev.h>
#include <linux/fsnotify.h>
#include <linux/security.h>

View File

@ -11,20 +11,12 @@
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/pagemap.h>
#include <linux/mpage.h>
#include <linux/buffer_head.h>
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/seq_file.h>
#include <linux/parser.h>
#include <linux/uio.h>
#include <linux/writeback.h>
#include <linux/log2.h>
#include <linux/hash.h>
#include <linux/blkdev.h>
#include <asm/unaligned.h>
#include "fat.h"
@ -1278,8 +1270,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
static int fat_read_root(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
int error;
MSDOS_I(inode)->i_pos = MSDOS_ROOT_INO;

View File

@ -6,10 +6,6 @@
* and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/time.h>
#include "fat.h"
/*

View File

@ -7,8 +7,6 @@
*/
#include <linux/module.h>
#include <linux/time.h>
#include <linux/buffer_head.h>
#include "fat.h"
/* Characters that are undesirable in an MS-DOS file name */

View File

@ -16,10 +16,8 @@
*/
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/buffer_head.h>
#include <linux/namei.h>
#include "fat.h"

View File

@ -638,8 +638,7 @@ static struct file *__fget(unsigned int fd, fmode_t mask)
file = fcheck_files(files, fd);
if (file) {
/* File object ref couldn't be taken */
if ((file->f_mode & mask) ||
!atomic_long_inc_not_zero(&file->f_count))
if ((file->f_mode & mask) || !get_file_rcu(file))
file = NULL;
}
rcu_read_unlock();

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