mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
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:
commit
54e514b91b
1
.gitignore
vendored
1
.gitignore
vendored
@ -24,6 +24,7 @@
|
||||
*.order
|
||||
*.elf
|
||||
*.bin
|
||||
*.tar
|
||||
*.gz
|
||||
*.bz2
|
||||
*.lzma
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
17
Documentation/devicetree/bindings/rtc/digicolor-rtc.txt
Normal file
17
Documentation/devicetree/bindings/rtc/digicolor-rtc.txt
Normal 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>;
|
||||
};
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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 */
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
10
arch/powerpc/include/asm/seccomp.h
Normal file
10
arch/powerpc/include/asm/seccomp.h
Normal 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 */
|
@ -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
|
||||
|
@ -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 */
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
@ -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 */
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include "intel_drv.h"
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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]);
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
||||
|
@ -244,12 +244,6 @@ error:
|
||||
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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
227
drivers/rtc/rtc-digicolor.c
Normal 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");
|
@ -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();
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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)");
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 },
|
||||
{ },
|
||||
};
|
||||
|
@ -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 |
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ int main(int argc, char **argv)
|
||||
case 'j':
|
||||
include_jump = 1;
|
||||
break;
|
||||
default:
|
||||
return usage();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 @@ error_free:
|
||||
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 @@ error_free_bh:
|
||||
error:
|
||||
sb->s_fs_info = NULL;
|
||||
kfree(asb);
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dentry *adfs_mount(struct file_system_type *fs_type,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 @@ got_root:
|
||||
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 @@ got_root:
|
||||
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 @@ got_root:
|
||||
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 @@ got_root:
|
||||
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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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';
|
||||
|
12
fs/exec.c
12
fs/exec.c
@ -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
|
||||
*/
|
||||
|
@ -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. */
|
||||
|
@ -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"
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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 @@ out:
|
||||
|
||||
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;
|
||||
|
@ -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"
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user