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 ...
Unified · Split
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | *.order |
| 25 | 25 | *.elf |
| 26 | 26 | *.bin |
| 27 | +*.tar | |
| 27 | 28 | *.gz |
| 28 | 29 | *.bz2 |
| 29 | 30 | *.lzma |
| @@ -659,6 +659,19 @@ macros using parameters. · 658 unmodified lines | ||
| 659 | 659 | #define CONSTANT 0x4000 |
| 660 | 660 | #define CONSTEXP (CONSTANT | 3) |
| 661 | 661 | |
| 662 | +5) namespace collisions when defining local variables in macros resembling | |
| 663 | +functions: | |
| 664 | + | |
| 665 | +#define FOO(x) \ | |
| 666 | +({ \ | |
| 667 | + typeof(x) ret; \ | |
| 668 | + ret = calc_ret(x); \ | |
| 669 | + (ret); \ | |
| 670 | +)} | |
| 671 | + | |
| 672 | +ret is a common name for a local variable - __foo_ret is less likely | |
| 673 | +to collide with an existing variable. | |
| 674 | + | |
| 662 | 675 | The cpp manual deals with macros exhaustively. The gcc internals manual also |
| 663 | 676 | covers RTL which is used frequently with assembly language in the kernel. |
| 664 | 677 | |
| @@ -614,8 +614,8 @@ The canonical patch message body contains the following: · 613 unmodified lines | ||
| 614 | 614 | |
| 615 | 615 | - An empty line. |
| 616 | 616 | |
| 617 | − - The body of the explanation, which will be copied to the | |
| 618 | − permanent changelog to describe this patch. | |
| 617 | + - The body of the explanation, line wrapped at 75 columns, which will | |
| 618 | + be copied to the permanent changelog to describe this patch. | |
| 619 | 619 | |
| 620 | 620 | - The "Signed-off-by:" lines, described above, which will |
| 621 | 621 | also go in the changelog. |
| @@ -0,0 +1,17 @@ | ||
| 1 | +Conexant Digicolor Real Time Clock controller | |
| 2 | + | |
| 3 | +This binding currently supports the CX92755 SoC. | |
| 4 | + | |
| 5 | +Required properties: | |
| 6 | +- compatible: should be "cnxt,cx92755-rtc" | |
| 7 | +- reg: physical base address of the controller and length of memory mapped | |
| 8 | + region. | |
| 9 | +- interrupts: rtc alarm interrupt | |
| 10 | + | |
| 11 | +Example: | |
| 12 | + | |
| 13 | + rtc@f0000c30 { | |
| 14 | + compatible = "cnxt,cx92755-rtc"; | |
| 15 | + reg = <0xf0000c30 0x18>; | |
| 16 | + interrupts = <25>; | |
| 17 | + }; | |
| @@ -7,6 +7,11 @@ Required properties: · 6 unmodified lines | ||
| 7 | 7 | region. |
| 8 | 8 | - interrupts: rtc alarm interrupt |
| 9 | 9 | |
| 10 | +Optional properties: | |
| 11 | +- stmp,crystal-freq: override crystal frequency as determined from fuse bits. | |
| 12 | + Only <32000> and <32768> are possible for the hardware. Use <0> for | |
| 13 | + "no crystal". | |
| 14 | + | |
| 10 | 15 | Example: |
| 11 | 16 | |
| 12 | 17 | rtc@80056000 { |
| @@ -200,12 +200,12 @@ contains details information about the process itself. Its fields are · 199 unmodified lines | ||
| 200 | 200 | explained in Table 1-4. |
| 201 | 201 | |
| 202 | 202 | (for SMP CONFIG users) |
| 203 | −For making accounting scalable, RSS related information are handled in | |
| 204 | −asynchronous manner and the vaule may not be very precise. To see a precise | |
| 203 | +For making accounting scalable, RSS related information are handled in an | |
| 204 | +asynchronous manner and the value may not be very precise. To see a precise | |
| 205 | 205 | snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table. |
| 206 | 206 | It's slow but very precise. |
| 207 | 207 | |
| 208 | −Table 1-2: Contents of the status files (as of 2.6.30-rc7) | |
| 208 | +Table 1-2: Contents of the status files (as of 3.20.0) | |
| 209 | 209 | .............................................................................. |
| 210 | 210 | Field Content |
| 211 | 211 | Name filename of the executable |
| @@ -213,6 +213,7 @@ Table 1-2: Contents of the status files (as of 2.6.30-rc7) · 1 unmodified line | ||
| 213 | 213 | in an uninterruptible wait, Z is zombie, |
| 214 | 214 | T is traced or stopped) |
| 215 | 215 | Tgid thread group ID |
| 216 | + Ngid NUMA group ID (0 if none) | |
| 216 | 217 | Pid process id |
| 217 | 218 | PPid process id of the parent process |
| 218 | 219 | 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) · 1 unmodified line | ||
| 220 | 221 | Gid Real, effective, saved set, and file system GIDs |
| 221 | 222 | FDSize number of file descriptor slots currently allocated |
| 222 | 223 | Groups supplementary group list |
| 224 | + NStgid descendant namespace thread group ID hierarchy | |
| 225 | + NSpid descendant namespace process ID hierarchy | |
| 226 | + NSpgid descendant namespace process group ID hierarchy | |
| 227 | + NSsid descendant namespace session ID hierarchy | |
| 223 | 228 | VmPeak peak virtual memory size |
| 224 | 229 | VmSize total program size |
| 225 | 230 | VmLck locked memory size |
| @@ -1704,6 +1709,10 @@ A typical output is · 1478 unmodified lines | ||
| 1704 | 1709 | flags: 0100002 |
| 1705 | 1710 | mnt_id: 19 |
| 1706 | 1711 | |
| 1712 | +All locks associated with a file descriptor are shown in its fdinfo too. | |
| 1713 | + | |
| 1714 | +lock: 1: FLOCK ADVISORY WRITE 359 00:13:11691 0 EOF | |
| 1715 | + | |
| 1707 | 1716 | The files such as eventfd, fsnotify, signalfd, epoll among the regular pos/flags |
| 1708 | 1717 | pair provide additional information particular to the objects they represent. |
| 1709 | 1718 | |
| @@ -80,7 +80,7 @@ static void hex_dump(const void *src, size_t length, size_t line_size, char *pre · 79 unmodified lines | ||
| 80 | 80 | * Unescape - process hexadecimal escape character |
| 81 | 81 | * converts shell input "\x23" -> 0x23 |
| 82 | 82 | */ |
| 83 | −int unespcape(char *_dst, char *_src, size_t len) | |
| 83 | +static int unescape(char *_dst, char *_src, size_t len) | |
| 84 | 84 | { |
| 85 | 85 | int ret = 0; |
| 86 | 86 | char *src = _src; |
| @@ -304,7 +304,7 @@ int main(int argc, char *argv[]) · 217 unmodified lines | ||
| 304 | 304 | size = strlen(input_tx+1); |
| 305 | 305 | tx = malloc(size); |
| 306 | 306 | rx = malloc(size); |
| 307 | − size = unespcape((char *)tx, input_tx, size); | |
| 307 | + size = unescape((char *)tx, input_tx, size); | |
| 308 | 308 | transfer(fd, tx, rx, size); |
| 309 | 309 | free(rx); |
| 310 | 310 | free(tx); |
| @@ -872,6 +872,27 @@ can be ORed together: · 871 unmodified lines | ||
| 872 | 872 | |
| 873 | 873 | ============================================================== |
| 874 | 874 | |
| 875 | +threads-max | |
| 876 | + | |
| 877 | +This value controls the maximum number of threads that can be created | |
| 878 | +using fork(). | |
| 879 | + | |
| 880 | +During initialization the kernel sets this value such that even if the | |
| 881 | +maximum number of threads is created, the thread structures occupy only | |
| 882 | +a part (1/8th) of the available RAM pages. | |
| 883 | + | |
| 884 | +The minimum value that can be written to threads-max is 20. | |
| 885 | +The maximum value that can be written to threads-max is given by the | |
| 886 | +constant FUTEX_TID_MASK (0x3fffffff). | |
| 887 | +If a value outside of this range is written to threads-max an error | |
| 888 | +EINVAL occurs. | |
| 889 | + | |
| 890 | +The value written is checked against the available RAM pages. If the | |
| 891 | +thread structures would occupy too much (more than 1/8th) of the | |
| 892 | +available RAM pages threads-max is reduced accordingly. | |
| 893 | + | |
| 894 | +============================================================== | |
| 895 | + | |
| 875 | 896 | unknown_nmi_panic: |
| 876 | 897 | |
| 877 | 898 | The value in this file affects behavior of handling NMI. When the |
| @@ -1215,6 +1215,7 @@ F: arch/arm/mach-orion5x/ts78xx-* · 1214 unmodified lines | ||
| 1215 | 1215 | ARM/Mediatek SoC support |
| 1216 | 1216 | M: Matthias Brugger <matthias.bgg@gmail.com> |
| 1217 | 1217 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1218 | +L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) | |
| 1218 | 1219 | S: Maintained |
| 1219 | 1220 | F: arch/arm/boot/dts/mt6* |
| 1220 | 1221 | F: arch/arm/boot/dts/mt8* |
| @@ -8183,6 +8184,7 @@ X: kernel/torture.c · 6962 unmodified lines | ||
| 8183 | 8184 | |
| 8184 | 8185 | REAL TIME CLOCK (RTC) SUBSYSTEM |
| 8185 | 8186 | M: Alessandro Zummo <a.zummo@towertech.it> |
| 8187 | +M: Alexandre Belloni <alexandre.belloni@free-electrons.com> | |
| 8186 | 8188 | L: rtc-linux@googlegroups.com |
| 8187 | 8189 | Q: http://patchwork.ozlabs.org/project/rtc-linux/list/ |
| 8188 | 8190 | S: Maintained |
| @@ -44,6 +44,7 @@ struct task_struct; · 43 unmodified lines | ||
| 44 | 44 | extern unsigned long thread_saved_pc(struct task_struct *); |
| 45 | 45 | |
| 46 | 46 | /* Do necessary setup to start up a newly executed thread. */ |
| 47 | +struct pt_regs; | |
| 47 | 48 | extern void start_thread(struct pt_regs *, unsigned long, unsigned long); |
| 48 | 49 | |
| 49 | 50 | /* Free all resources held by a thread. */ |
| @@ -52,7 +52,7 @@ static void show_callee_regs(struct callee_regs *cregs) · 51 unmodified lines | ||
| 52 | 52 | print_reg_file(&(cregs->r13), 13); |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | −void print_task_path_n_nm(struct task_struct *tsk, char *buf) | |
| 55 | +static void print_task_path_n_nm(struct task_struct *tsk, char *buf) | |
| 56 | 56 | { |
| 57 | 57 | struct path path; |
| 58 | 58 | char *path_nm = NULL; |
| @@ -77,7 +77,6 @@ void print_task_path_n_nm(struct task_struct *tsk, char *buf) · 18 unmodified lines | ||
| 77 | 77 | done: |
| 78 | 78 | pr_info("Path: %s\n", path_nm); |
| 79 | 79 | } |
| 80 | −EXPORT_SYMBOL(print_task_path_n_nm); | |
| 81 | 80 | |
| 82 | 81 | static void show_faulting_vma(unsigned long address, char *buf) |
| 83 | 82 | { |
| @@ -21,6 +21,7 @@ generic-y += preempt.h · 20 unmodified lines | ||
| 21 | 21 | generic-y += resource.h |
| 22 | 22 | generic-y += rwsem.h |
| 23 | 23 | generic-y += scatterlist.h |
| 24 | +generic-y += seccomp.h | |
| 24 | 25 | generic-y += sections.h |
| 25 | 26 | generic-y += segment.h |
| 26 | 27 | generic-y += sembuf.h |
| @@ -1,11 +0,0 @@ | ||
| 1 | −#ifndef _ASM_ARM_SECCOMP_H | |
| 2 | −#define _ASM_ARM_SECCOMP_H | |
| 3 | − | |
| 4 | −#include <linux/unistd.h> | |
| 5 | − | |
| 6 | −#define __NR_seccomp_read __NR_read | |
| 7 | −#define __NR_seccomp_write __NR_write | |
| 8 | −#define __NR_seccomp_exit __NR_exit | |
| 9 | −#define __NR_seccomp_sigreturn __NR_rt_sigreturn | |
| 10 | − | |
| 11 | −#endif /* _ASM_ARM_SECCOMP_H */ | |
| @@ -3,14 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | #include <linux/unistd.h> |
| 5 | 5 | |
| 6 | −#define __NR_seccomp_read __NR_read | |
| 7 | −#define __NR_seccomp_write __NR_write | |
| 8 | −#define __NR_seccomp_exit __NR_exit | |
| 9 | 6 | #define __NR_seccomp_sigreturn __NR_sigreturn |
| 10 | 7 | |
| 11 | −#define __NR_seccomp_read_32 __NR_read | |
| 12 | −#define __NR_seccomp_write_32 __NR_write | |
| 13 | −#define __NR_seccomp_exit_32 __NR_exit | |
| 14 | −#define __NR_seccomp_sigreturn_32 __NR_sigreturn | |
| 8 | +#include <asm-generic/seccomp.h> | |
| 15 | 9 | |
| 16 | 10 | #endif /* _ASM_MICROBLAZE_SECCOMP_H */ |
| @@ -105,7 +105,8 @@ CONFIG_RTC_CLASS=y · 104 unmodified lines | ||
| 105 | 105 | # CONFIG_RTC_HCTOSYS is not set |
| 106 | 106 | # CONFIG_RTC_INTF_SYSFS is not set |
| 107 | 107 | # CONFIG_RTC_INTF_PROC is not set |
| 108 | −CONFIG_RTC_DRV_CMOS=y | |
| 108 | +CONFIG_RTC_DRV_DS1685_FAMILY=y | |
| 109 | +CONFIG_RTC_DRV_DS1685=y | |
| 109 | 110 | CONFIG_EXT2_FS=y |
| 110 | 111 | CONFIG_EXT2_FS_XATTR=y |
| 111 | 112 | CONFIG_EXT2_FS_POSIX_ACL=y |
| @@ -1,36 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | − * License. See the file "COPYING" in the main directory of this archive | |
| 4 | − * for more details. | |
| 5 | − * | |
| 6 | − * Copyright (C) 1998, 2001, 03 by Ralf Baechle | |
| 7 | − * Copyright (C) 2000 Harald Koerfgen | |
| 8 | − * | |
| 9 | − * RTC routines for IP32 style attached Dallas chip. | |
| 10 | − */ | |
| 11 | −#ifndef __ASM_MACH_IP32_MC146818RTC_H | |
| 12 | −#define __ASM_MACH_IP32_MC146818RTC_H | |
| 13 | − | |
| 14 | −#include <asm/ip32/mace.h> | |
| 15 | − | |
| 16 | −#define RTC_PORT(x) (0x70 + (x)) | |
| 17 | − | |
| 18 | −static unsigned char CMOS_READ(unsigned long addr) | |
| 19 | −{ | |
| 20 | − return mace->isa.rtc[addr << 8]; | |
| 21 | −} | |
| 22 | − | |
| 23 | −static inline void CMOS_WRITE(unsigned char data, unsigned long addr) | |
| 24 | −{ | |
| 25 | − mace->isa.rtc[addr << 8] = data; | |
| 26 | −} | |
| 27 | − | |
| 28 | −/* | |
| 29 | − * FIXME: Do it right. For now just assume that no one lives in 20th century | |
| 30 | − * and no O2 user in 22th century ;-) | |
| 31 | − */ | |
| 32 | −#define mc146818_decode_year(year) ((year) + 2000) | |
| 33 | − | |
| 34 | −#define RTC_ALWAYS_BCD 0 | |
| 35 | − | |
| 36 | −#endif /* __ASM_MACH_IP32_MC146818RTC_H */ | |
| @@ -2,11 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | #include <linux/unistd.h> |
| 4 | 4 | |
| 5 | −#define __NR_seccomp_read __NR_read | |
| 6 | −#define __NR_seccomp_write __NR_write | |
| 7 | −#define __NR_seccomp_exit __NR_exit | |
| 8 | −#define __NR_seccomp_sigreturn __NR_rt_sigreturn | |
| 9 | − | |
| 10 | 5 | /* |
| 11 | 6 | * Kludge alert: |
| 12 | 7 | * |
| @@ -29,4 +24,6 @@ · 16 unmodified lines | ||
| 29 | 24 | |
| 30 | 25 | #endif /* CONFIG_MIPS32_O32 */ |
| 31 | 26 | |
| 27 | +#include <asm-generic/seccomp.h> | |
| 28 | + | |
| 32 | 29 | #endif /* __ASM_SECCOMP_H */ |
| @@ -9,10 +9,13 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/init.h> |
| 10 | 10 | #include <linux/platform_device.h> |
| 11 | 11 | #include <linux/serial_8250.h> |
| 12 | +#include <linux/rtc/ds1685.h> | |
| 12 | 13 | |
| 13 | 14 | #include <asm/ip32/mace.h> |
| 14 | 15 | #include <asm/ip32/ip32_ints.h> |
| 15 | 16 | |
| 17 | +extern void ip32_prepare_poweroff(void); | |
| 18 | + | |
| 16 | 19 | #define MACEISA_SERIAL1_OFFS offsetof(struct sgi_mace, isa.serial1) |
| 17 | 20 | #define MACEISA_SERIAL2_OFFS offsetof(struct sgi_mace, isa.serial2) |
| 18 | 21 | |
| @@ -90,18 +93,47 @@ static __init int sgio2btns_devinit(void) · 71 unmodified lines | ||
| 90 | 93 | |
| 91 | 94 | device_initcall(sgio2btns_devinit); |
| 92 | 95 | |
| 93 | −static struct resource sgio2_cmos_rsrc[] = { | |
| 96 | +#define MACE_RTC_RES_START (MACE_BASE + offsetof(struct sgi_mace, isa.rtc)) | |
| 97 | +#define MACE_RTC_RES_END (MACE_RTC_RES_START + 32767) | |
| 98 | + | |
| 99 | +static struct resource ip32_rtc_resources[] = { | |
| 94 | 100 | { |
| 95 | − .start = 0x70, | |
| 96 | − .end = 0x71, | |
| 97 | − .flags = IORESOURCE_IO | |
| 101 | + .start = MACEISA_RTC_IRQ, | |
| 102 | + .end = MACEISA_RTC_IRQ, | |
| 103 | + .flags = IORESOURCE_IRQ | |
| 104 | + }, { | |
| 105 | + .start = MACE_RTC_RES_START, | |
| 106 | + .end = MACE_RTC_RES_END, | |
| 107 | + .flags = IORESOURCE_MEM, | |
| 98 | 108 | } |
| 99 | 109 | }; |
| 100 | 110 | |
| 101 | −static __init int sgio2_cmos_devinit(void) | |
| 111 | +/* RTC registers on IP32 are each padded by 256 bytes (0x100). */ | |
| 112 | +static struct ds1685_rtc_platform_data | |
| 113 | +ip32_rtc_platform_data[] = { | |
| 114 | + { | |
| 115 | + .regstep = 0x100, | |
| 116 | + .bcd_mode = true, | |
| 117 | + .no_irq = false, | |
| 118 | + .uie_unsupported = false, | |
| 119 | + .alloc_io_resources = true, | |
| 120 | + .plat_prepare_poweroff = ip32_prepare_poweroff, | |
| 121 | + }, | |
| 122 | +}; | |
| 123 | + | |
| 124 | +struct platform_device ip32_rtc_device = { | |
| 125 | + .name = "rtc-ds1685", | |
| 126 | + .id = -1, | |
| 127 | + .dev = { | |
| 128 | + .platform_data = ip32_rtc_platform_data, | |
| 129 | + }, | |
| 130 | + .num_resources = ARRAY_SIZE(ip32_rtc_resources), | |
| 131 | + .resource = ip32_rtc_resources, | |
| 132 | +}; | |
| 133 | + | |
| 134 | ++static int __init sgio2_rtc_devinit(void) | |
| 102 | 135 | { |
| 103 | − return IS_ERR(platform_device_register_simple("rtc_cmos", -1, | |
| 104 | − sgio2_cmos_rsrc, 1)); | |
| 136 | + return platform_device_register(&ip32_rtc_device); | |
| 105 | 137 | } |
| 106 | 138 | |
| 107 | 139 | device_initcall(sgio2_cmos_devinit); |
| @@ -11,10 +11,11 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/compiler.h> |
| 12 | 12 | #include <linux/init.h> |
| 13 | 13 | #include <linux/kernel.h> |
| 14 | +#include <linux/module.h> | |
| 14 | 15 | #include <linux/sched.h> |
| 15 | 16 | #include <linux/notifier.h> |
| 16 | 17 | #include <linux/delay.h> |
| 17 | −#include <linux/ds17287rtc.h> | |
| 18 | +#include <linux/rtc/ds1685.h> | |
| 18 | 19 | #include <linux/interrupt.h> |
| 19 | 20 | #include <linux/pm.h> |
| 20 | 21 | |
| @@ -33,53 +34,40 @@ · 12 unmodified lines | ||
| 33 | 34 | #define POWERDOWN_FREQ (HZ / 4) |
| 34 | 35 | #define PANIC_FREQ (HZ / 8) |
| 35 | 36 | |
| 36 | −static struct timer_list power_timer, blink_timer, debounce_timer; | |
| 37 | −static int has_panicked, shuting_down; | |
| 37 | +extern struct platform_device ip32_rtc_device; | |
| 38 | 38 | |
| 39 | −static void ip32_machine_restart(char *command) __noreturn; | |
| 40 | −static void ip32_machine_halt(void) __noreturn; | |
| 41 | −static void ip32_machine_power_off(void) __noreturn; | |
| 39 | +static struct timer_list power_timer, blink_timer; | |
| 40 | +static int has_panicked, shutting_down; | |
| 42 | 41 | |
| 43 | −static void ip32_machine_restart(char *cmd) | |
| 42 | +static __noreturn void ip32_poweroff(void *data) | |
| 44 | 43 | { |
| 45 | − crime->control = CRIME_CONTROL_HARD_RESET; | |
| 46 | − while (1); | |
| 47 | −} | |
| 44 | + void (*poweroff_func)(struct platform_device *) = | |
| 45 | + symbol_get(ds1685_rtc_poweroff); | |
| 46 | + | |
| 47 | +#ifdef CONFIG_MODULES | |
| 48 | + /* If the first __symbol_get failed, our module wasn't loaded. */ | |
| 49 | + if (!poweroff_func) { | |
| 50 | + request_module("rtc-ds1685"); | |
| 51 | + poweroff_func = symbol_get(ds1685_rtc_poweroff); | |
| 52 | + } | |
| 53 | +#endif | |
| 48 | 54 | |
| 49 | −static inline void ip32_machine_halt(void) | |
| 50 | −{ | |
| 51 | − ip32_machine_power_off(); | |
| 52 | −} | |
| 55 | + if (!poweroff_func) | |
| 56 | + pr_emerg("RTC not available for power-off. Spinning forever ...\n"); | |
| 57 | + else { | |
| 58 | + (*poweroff_func)((struct platform_device *)data); | |
| 59 | + symbol_put(ds1685_rtc_poweroff); | |
| 60 | + } | |
| 53 | 61 | |
| 54 | −static void ip32_machine_power_off(void) | |
| 55 | −{ | |
| 56 | − unsigned char reg_a, xctrl_a, xctrl_b; | |
| 57 | − | |
| 58 | − disable_irq(MACEISA_RTC_IRQ); | |
| 59 | − reg_a = CMOS_READ(RTC_REG_A); | |
| 60 | − | |
| 61 | − /* setup for kickstart & wake-up (DS12287 Ref. Man. p. 19) */ | |
| 62 | − reg_a &= ~DS_REGA_DV2; | |
| 63 | − reg_a |= DS_REGA_DV1; | |
| 64 | − | |
| 65 | − CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A); | |
| 66 | − wbflush(); | |
| 67 | − xctrl_b = CMOS_READ(DS_B1_XCTRL4B) | |
| 68 | − | DS_XCTRL4B_ABE | DS_XCTRL4B_KFE; | |
| 69 | − CMOS_WRITE(xctrl_b, DS_B1_XCTRL4B); | |
| 70 | − xctrl_a = CMOS_READ(DS_B1_XCTRL4A) & ~DS_XCTRL4A_IFS; | |
| 71 | − CMOS_WRITE(xctrl_a, DS_B1_XCTRL4A); | |
| 72 | − wbflush(); | |
| 73 | − /* adios amigos... */ | |
| 74 | − CMOS_WRITE(xctrl_a | DS_XCTRL4A_PAB, DS_B1_XCTRL4A); | |
| 75 | − CMOS_WRITE(reg_a, RTC_REG_A); | |
| 76 | − wbflush(); | |
| 77 | − while (1); | |
| 62 | + unreachable(); | |
| 78 | 63 | } |
| 79 | 64 | |
| 80 | −static void power_timeout(unsigned long data) | |
| 65 | +static void ip32_machine_restart(char *cmd) __noreturn; | |
| 66 | +static void ip32_machine_restart(char *cmd) | |
| 81 | 67 | { |
| 82 | − ip32_machine_power_off(); | |
| 68 | + msleep(20); | |
| 69 | + crime->control = CRIME_CONTROL_HARD_RESET; | |
| 70 | + unreachable(); | |
| 83 | 71 | } |
| 84 | 72 | |
| 85 | 73 | static void blink_timeout(unsigned long data) |
| @@ -89,44 +77,27 @@ static void blink_timeout(unsigned long data) · 3 unmodified lines | ||
| 89 | 77 | mod_timer(&blink_timer, jiffies + data); |
| 90 | 78 | } |
| 91 | 79 | |
| 92 | −static void debounce(unsigned long data) | |
| 80 | +static void ip32_machine_halt(void) | |
| 93 | 81 | { |
| 94 | − unsigned char reg_a, reg_c, xctrl_a; | |
| 95 | − | |
| 96 | − reg_c = CMOS_READ(RTC_INTR_FLAGS); | |
| 97 | − reg_a = CMOS_READ(RTC_REG_A); | |
| 98 | − CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A); | |
| 99 | − wbflush(); | |
| 100 | − xctrl_a = CMOS_READ(DS_B1_XCTRL4A); | |
| 101 | − if ((xctrl_a & DS_XCTRL4A_IFS) || (reg_c & RTC_IRQF )) { | |
| 102 | − /* Interrupt still being sent. */ | |
| 103 | − debounce_timer.expires = jiffies + 50; | |
| 104 | − add_timer(&debounce_timer); | |
| 105 | − | |
| 106 | − /* clear interrupt source */ | |
| 107 | − CMOS_WRITE(xctrl_a & ~DS_XCTRL4A_IFS, DS_B1_XCTRL4A); | |
| 108 | − CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A); | |
| 109 | − return; | |
| 110 | − } | |
| 111 | − CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A); | |
| 112 | − | |
| 113 | − if (has_panicked) | |
| 114 | − ip32_machine_restart(NULL); | |
| 82 | + ip32_poweroff(&ip32_rtc_device); | |
| 83 | +} | |
| 115 | 84 | |
| 116 | − enable_irq(MACEISA_RTC_IRQ); | |
| 85 | +static void power_timeout(unsigned long data) | |
| 86 | +{ | |
| 87 | + ip32_poweroff(&ip32_rtc_device); | |
| 117 | 88 | } |
| 118 | 89 | |
| 119 | −static inline void ip32_power_button(void) | |
| 90 | +void ip32_prepare_poweroff(void) | |
| 120 | 91 | { |
| 121 | 92 | if (has_panicked) |
| 122 | 93 | return; |
| 123 | 94 | |
| 124 | − if (shuting_down || kill_cad_pid(SIGINT, 1)) { | |
| 95 | + if (shutting_down || kill_cad_pid(SIGINT, 1)) { | |
| 125 | 96 | /* No init process or button pressed twice. */ |
| 126 | − ip32_machine_power_off(); | |
| 97 | + ip32_poweroff(&ip32_rtc_device); | |
| 127 | 98 | } |
| 128 | 99 | |
| 129 | − shuting_down = 1; | |
| 100 | + shutting_down = 1; | |
| 130 | 101 | blink_timer.data = POWERDOWN_FREQ; |
| 131 | 102 | blink_timeout(POWERDOWN_FREQ); |
| 132 | 103 | |
| @@ -136,27 +107,6 @@ static inline void ip32_power_button(void) · 3 unmodified lines | ||
| 136 | 107 | add_timer(&power_timer); |
| 137 | 108 | } |
| 138 | 109 | |
| 139 | −static irqreturn_t ip32_rtc_int(int irq, void *dev_id) | |
| 140 | −{ | |
| 141 | − unsigned char reg_c; | |
| 142 | − | |
| 143 | − reg_c = CMOS_READ(RTC_INTR_FLAGS); | |
| 144 | − if (!(reg_c & RTC_IRQF)) { | |
| 145 | − printk(KERN_WARNING | |
| 146 | − "%s: RTC IRQ without RTC_IRQF\n", __func__); | |
| 147 | − } | |
| 148 | − /* Wait until interrupt goes away */ | |
| 149 | − disable_irq_nosync(MACEISA_RTC_IRQ); | |
| 150 | − init_timer(&debounce_timer); | |
| 151 | − debounce_timer.function = debounce; | |
| 152 | − debounce_timer.expires = jiffies + 50; | |
| 153 | − add_timer(&debounce_timer); | |
| 154 | − | |
| 155 | − printk(KERN_DEBUG "Power button pressed\n"); | |
| 156 | − ip32_power_button(); | |
| 157 | − return IRQ_HANDLED; | |
| 158 | −} | |
| 159 | − | |
| 160 | 110 | static int panic_event(struct notifier_block *this, unsigned long event, |
| 161 | 111 | void *ptr) |
| 162 | 112 | { |
| @@ -190,15 +140,12 @@ static __init int ip32_reboot_setup(void) · 27 unmodified lines | ||
| 190 | 140 | |
| 191 | 141 | _machine_restart = ip32_machine_restart; |
| 192 | 142 | _machine_halt = ip32_machine_halt; |
| 193 | − pm_power_off = ip32_machine_power_off; | |
| 143 | + pm_power_off = ip32_machine_halt; | |
| 194 | 144 | |
| 195 | 145 | init_timer(&blink_timer); |
| 196 | 146 | blink_timer.function = blink_timeout; |
| 197 | 147 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); |
| 198 | 148 | |
| 199 | − if (request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL)) | |
| 200 | − panic("Can't allocate MACEISA RTC IRQ"); | |
| 201 | − | |
| 202 | 149 | return 0; |
| 203 | 150 | } |
| 204 | 151 | |
| @@ -20,6 +20,7 @@ generic-y += param.h · 19 unmodified lines | ||
| 20 | 20 | generic-y += percpu.h |
| 21 | 21 | generic-y += poll.h |
| 22 | 22 | generic-y += preempt.h |
| 23 | +generic-y += seccomp.h | |
| 23 | 24 | generic-y += segment.h |
| 24 | 25 | generic-y += topology.h |
| 25 | 26 | generic-y += trace_clock.h |
| @@ -1,16 +0,0 @@ | ||
| 1 | −#ifndef _ASM_PARISC_SECCOMP_H | |
| 2 | −#define _ASM_PARISC_SECCOMP_H | |
| 3 | − | |
| 4 | −#include <linux/unistd.h> | |
| 5 | − | |
| 6 | −#define __NR_seccomp_read __NR_read | |
| 7 | −#define __NR_seccomp_write __NR_write | |
| 8 | −#define __NR_seccomp_exit __NR_exit | |
| 9 | −#define __NR_seccomp_sigreturn __NR_rt_sigreturn | |
| 10 | − | |
| 11 | −#define __NR_seccomp_read_32 __NR_read | |
| 12 | −#define __NR_seccomp_write_32 __NR_write | |
| 13 | −#define __NR_seccomp_exit_32 __NR_exit | |
| 14 | −#define __NR_seccomp_sigreturn_32 __NR_rt_sigreturn | |
| 15 | − | |
| 16 | −#endif /* _ASM_PARISC_SECCOMP_H */ | |
| @@ -0,0 +1,10 @@ | ||
| 1 | +#ifndef _ASM_POWERPC_SECCOMP_H | |
| 2 | +#define _ASM_POWERPC_SECCOMP_H | |
| 3 | + | |
| 4 | +#include <linux/unistd.h> | |
| 5 | + | |
| 6 | +#define __NR_seccomp_sigreturn_32 __NR_sigreturn | |
| 7 | + | |
| 8 | +#include <asm-generic/seccomp.h> | |
| 9 | + | |
| 10 | +#endif /* _ASM_POWERPC_SECCOMP_H */ | |
| @@ -25,7 +25,6 @@ header-y += posix_types.h · 24 unmodified lines | ||
| 25 | 25 | header-y += ps3fb.h |
| 26 | 26 | header-y += ptrace.h |
| 27 | 27 | header-y += resource.h |
| 28 | −header-y += seccomp.h | |
| 29 | 28 | header-y += sembuf.h |
| 30 | 29 | header-y += setup.h |
| 31 | 30 | header-y += shmbuf.h |
| @@ -1,16 +0,0 @@ | ||
| 1 | −#ifndef _ASM_POWERPC_SECCOMP_H | |
| 2 | −#define _ASM_POWERPC_SECCOMP_H | |
| 3 | − | |
| 4 | −#include <linux/unistd.h> | |
| 5 | − | |
| 6 | −#define __NR_seccomp_read __NR_read | |
| 7 | −#define __NR_seccomp_write __NR_write | |
| 8 | −#define __NR_seccomp_exit __NR_exit | |
| 9 | −#define __NR_seccomp_sigreturn __NR_rt_sigreturn | |
| 10 | − | |
| 11 | −#define __NR_seccomp_read_32 __NR_read | |
| 12 | −#define __NR_seccomp_write_32 __NR_write | |
| 13 | −#define __NR_seccomp_exit_32 __NR_exit | |
| 14 | −#define __NR_seccomp_sigreturn_32 __NR_sigreturn | |
| 15 | − | |
| 16 | −#endif /* _ASM_POWERPC_SECCOMP_H */ | |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/kref.h> |
| 23 | 23 | #include <linux/mm.h> |
| 24 | 24 | #include <linux/fs.h> |
| 25 | +#include <linux/file.h> | |
| 25 | 26 | #include <linux/module.h> |
| 26 | 27 | #include <linux/notifier.h> |
| 27 | 28 | #include <linux/numa.h> |
| @@ -322,18 +323,20 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, · 294 unmodified lines | ||
| 322 | 323 | unsigned long app_cookie = 0; |
| 323 | 324 | unsigned int my_offset = 0; |
| 324 | 325 | struct vm_area_struct *vma; |
| 326 | + struct file *exe_file; | |
| 325 | 327 | struct mm_struct *mm = spu->mm; |
| 326 | 328 | |
| 327 | 329 | if (!mm) |
| 328 | 330 | goto out; |
| 329 | 331 | |
| 330 | − down_read(&mm->mmap_sem); | |
| 331 | − | |
| 332 | − if (mm->exe_file) { | |
| 333 | − app_cookie = fast_get_dcookie(&mm->exe_file->f_path); | |
| 334 | − pr_debug("got dcookie for %pD\n", mm->exe_file); | |
| 332 | + exe_file = get_mm_exe_file(mm); | |
| 333 | + if (exe_file) { | |
| 334 | + app_cookie = fast_get_dcookie(&exe_file->f_path); | |
| 335 | + pr_debug("got dcookie for %pD\n", exe_file); | |
| 336 | + fput(exe_file); | |
| 335 | 337 | } |
| 336 | 338 | |
| 339 | + down_read(&mm->mmap_sem); | |
| 337 | 340 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
| 338 | 341 | if (vma->vm_start > spu_ref || vma->vm_end <= spu_ref) |
| 339 | 342 | continue; |
| @@ -1,15 +1,10 @@ | ||
| 1 | 1 | #ifndef _ASM_SECCOMP_H |
| 2 | +#define _ASM_SECCOMP_H | |
| 2 | 3 | |
| 3 | 4 | #include <linux/unistd.h> |
| 4 | 5 | |
| 5 | −#define __NR_seccomp_read __NR_read | |
| 6 | −#define __NR_seccomp_write __NR_write | |
| 7 | −#define __NR_seccomp_exit __NR_exit | |
| 8 | −#define __NR_seccomp_sigreturn __NR_rt_sigreturn | |
| 9 | − | |
| 10 | −#define __NR_seccomp_read_32 __NR_read | |
| 11 | −#define __NR_seccomp_write_32 __NR_write | |
| 12 | −#define __NR_seccomp_exit_32 __NR_exit | |
| 13 | 6 | #define __NR_seccomp_sigreturn_32 __NR_sigreturn |
| 14 | 7 | |
| 8 | +#include <asm-generic/seccomp.h> | |
| 9 | + | |
| 15 | 10 | #endif /* _ASM_SECCOMP_H */ |
| @@ -1,5 +1,20 @@ | ||
| 1 | +#ifndef _ASM_X86_SECCOMP_H | |
| 2 | +#define _ASM_X86_SECCOMP_H | |
| 3 | + | |
| 4 | +#include <asm/unistd.h> | |
| 5 | + | |
| 1 | 6 | #ifdef CONFIG_X86_32 |
| 2 | −# include <asm/seccomp_32.h> | |
| 3 | −#else | |
| 4 | −# include <asm/seccomp_64.h> | |
| 7 | +#define __NR_seccomp_sigreturn __NR_sigreturn | |
| 5 | 8 | #endif |
| 9 | + | |
| 10 | +#ifdef CONFIG_COMPAT | |
| 11 | +#include <asm/ia32_unistd.h> | |
| 12 | +#define __NR_seccomp_read_32 __NR_ia32_read | |
| 13 | +#define __NR_seccomp_write_32 __NR_ia32_write | |
| 14 | +#define __NR_seccomp_exit_32 __NR_ia32_exit | |
| 15 | +#define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn | |
| 16 | +#endif | |
| 17 | + | |
| 18 | +#include <asm-generic/seccomp.h> | |
| 19 | + | |
| 20 | +#endif /* _ASM_X86_SECCOMP_H */ | |
| @@ -1,11 +0,0 @@ | ||
| 1 | −#ifndef _ASM_X86_SECCOMP_32_H | |
| 2 | −#define _ASM_X86_SECCOMP_32_H | |
| 3 | − | |
| 4 | −#include <linux/unistd.h> | |
| 5 | − | |
| 6 | −#define __NR_seccomp_read __NR_read | |
| 7 | −#define __NR_seccomp_write __NR_write | |
| 8 | −#define __NR_seccomp_exit __NR_exit | |
| 9 | −#define __NR_seccomp_sigreturn __NR_sigreturn | |
| 10 | − | |
| 11 | −#endif /* _ASM_X86_SECCOMP_32_H */ | |
| @@ -1,17 +0,0 @@ | ||
| 1 | −#ifndef _ASM_X86_SECCOMP_64_H | |
| 2 | −#define _ASM_X86_SECCOMP_64_H | |
| 3 | − | |
| 4 | −#include <linux/unistd.h> | |
| 5 | −#include <asm/ia32_unistd.h> | |
| 6 | − | |
| 7 | −#define __NR_seccomp_read __NR_read | |
| 8 | −#define __NR_seccomp_write __NR_write | |
| 9 | −#define __NR_seccomp_exit __NR_exit | |
| 10 | −#define __NR_seccomp_sigreturn __NR_rt_sigreturn | |
| 11 | − | |
| 12 | −#define __NR_seccomp_read_32 __NR_ia32_read | |
| 13 | −#define __NR_seccomp_write_32 __NR_ia32_write | |
| 14 | −#define __NR_seccomp_exit_32 __NR_ia32_exit | |
| 15 | −#define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn | |
| 16 | − | |
| 17 | −#endif /* _ASM_X86_SECCOMP_64_H */ | |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include "clk-kona.h" |
| 16 | 16 | |
| 17 | 17 | #include <linux/delay.h> |
| 18 | +#include <linux/kernel.h> | |
| 18 | 19 | |
| 19 | 20 | /* |
| 20 | 21 | * "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) · 30 unmodified lines | ||
| 51 | 52 | |
| 52 | 53 | /* Divider and scaling helpers */ |
| 53 | 54 | |
| 54 | −/* | |
| 55 | − * Implement DIV_ROUND_CLOSEST() for 64-bit dividend and both values | |
| 56 | − * unsigned. Note that unlike do_div(), the remainder is discarded | |
| 57 | − * and the return value is the quotient (not the remainder). | |
| 58 | − */ | |
| 59 | −u64 do_div_round_closest(u64 dividend, unsigned long divisor) | |
| 60 | −{ | |
| 61 | − u64 result; | |
| 62 | − | |
| 63 | − result = dividend + ((u64)divisor >> 1); | |
| 64 | − (void)do_div(result, divisor); | |
| 65 | − | |
| 66 | − return result; | |
| 67 | −} | |
| 68 | − | |
| 69 | 55 | /* Convert a divider into the scaled divisor value it represents. */ |
| 70 | 56 | static inline u64 scaled_div_value(struct bcm_clk_div *div, u32 reg_div) |
| 71 | 57 | { |
| @@ -87,7 +73,7 @@ u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, u32 billionths) · 15 unmodified lines | ||
| 87 | 73 | combined = (u64)div_value * BILLION + billionths; |
| 88 | 74 | combined <<= div->u.s.frac_width; |
| 89 | 75 | |
| 90 | − return do_div_round_closest(combined, BILLION); | |
| 76 | + return DIV_ROUND_CLOSEST_ULL(combined, BILLION); | |
| 91 | 77 | } |
| 92 | 78 | |
| 93 | 79 | /* The scaled minimum divisor representable by a divider */ |
| @@ -731,7 +717,7 @@ static unsigned long clk_recalc_rate(struct ccu_data *ccu, · 637 unmodified lines | ||
| 731 | 717 | scaled_rate = scale_rate(pre_div, parent_rate); |
| 732 | 718 | scaled_rate = scale_rate(div, scaled_rate); |
| 733 | 719 | scaled_div = divider_read_scaled(ccu, pre_div); |
| 734 | − scaled_parent_rate = do_div_round_closest(scaled_rate, | |
| 720 | + scaled_parent_rate = DIV_ROUND_CLOSEST_ULL(scaled_rate, | |
| 735 | 721 | scaled_div); |
| 736 | 722 | } else { |
| 737 | 723 | scaled_parent_rate = scale_rate(div, parent_rate); |
| @@ -743,7 +729,7 @@ static unsigned long clk_recalc_rate(struct ccu_data *ccu, · 5 unmodified lines | ||
| 743 | 729 | * rate. |
| 744 | 730 | */ |
| 745 | 731 | scaled_div = divider_read_scaled(ccu, div); |
| 746 | − result = do_div_round_closest(scaled_parent_rate, scaled_div); | |
| 732 | + result = DIV_ROUND_CLOSEST_ULL(scaled_parent_rate, scaled_div); | |
| 747 | 733 | |
| 748 | 734 | return (unsigned long)result; |
| 749 | 735 | } |
| @@ -790,7 +776,7 @@ static long round_rate(struct ccu_data *ccu, struct bcm_clk_div *div, · 40 unmodified lines | ||
| 790 | 776 | scaled_rate = scale_rate(pre_div, parent_rate); |
| 791 | 777 | scaled_rate = scale_rate(div, scaled_rate); |
| 792 | 778 | scaled_pre_div = divider_read_scaled(ccu, pre_div); |
| 793 | − scaled_parent_rate = do_div_round_closest(scaled_rate, | |
| 779 | + scaled_parent_rate = DIV_ROUND_CLOSEST_ULL(scaled_rate, | |
| 794 | 780 | scaled_pre_div); |
| 795 | 781 | } else { |
| 796 | 782 | 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, · 5 unmodified lines | ||
| 802 | 788 | * the best we can do. |
| 803 | 789 | */ |
| 804 | 790 | if (!divider_is_fixed(div)) { |
| 805 | − best_scaled_div = do_div_round_closest(scaled_parent_rate, | |
| 791 | + best_scaled_div = DIV_ROUND_CLOSEST_ULL(scaled_parent_rate, | |
| 806 | 792 | rate); |
| 807 | 793 | min_scaled_div = scaled_div_min(div); |
| 808 | 794 | max_scaled_div = scaled_div_max(div); |
| @@ -815,7 +801,7 @@ static long round_rate(struct ccu_data *ccu, struct bcm_clk_div *div, · 6 unmodified lines | ||
| 815 | 801 | } |
| 816 | 802 | |
| 817 | 803 | /* OK, figure out the resulting rate */ |
| 818 | − result = do_div_round_closest(scaled_parent_rate, best_scaled_div); | |
| 804 | + result = DIV_ROUND_CLOSEST_ULL(scaled_parent_rate, best_scaled_div); | |
| 819 | 805 | |
| 820 | 806 | if (scaled_div) |
| 821 | 807 | *scaled_div = best_scaled_div; |
| @@ -503,7 +503,6 @@ extern struct clk_ops kona_peri_clk_ops; · 502 unmodified lines | ||
| 503 | 503 | |
| 504 | 504 | /* Externally visible functions */ |
| 505 | 505 | |
| 506 | −extern u64 do_div_round_closest(u64 dividend, unsigned long divisor); | |
| 507 | 506 | extern u64 scaled_div_max(struct bcm_clk_div *div); |
| 508 | 507 | extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, |
| 509 | 508 | u32 billionths); |
| @@ -190,12 +190,6 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices); · 189 unmodified lines | ||
| 190 | 190 | |
| 191 | 191 | static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev); |
| 192 | 192 | |
| 193 | −/* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */ | |
| 194 | −static u64 div_round64(u64 dividend, u32 divisor) | |
| 195 | −{ | |
| 196 | − return div_u64(dividend + (divisor / 2), divisor); | |
| 197 | −} | |
| 198 | − | |
| 199 | 193 | /* |
| 200 | 194 | * Try detecting repeating patterns by keeping track of the last 8 |
| 201 | 195 | * 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) · 115 unmodified lines | ||
| 317 | 311 | * operands are 32 bits. |
| 318 | 312 | * Make sure to round up for half microseconds. |
| 319 | 313 | */ |
| 320 | − data->predicted_us = div_round64((uint64_t)data->next_timer_us * | |
| 314 | + data->predicted_us = DIV_ROUND_CLOSEST_ULL((uint64_t)data->next_timer_us * | |
| 321 | 315 | data->correction_factor[data->bucket], |
| 322 | 316 | RESOLUTION * DECAY); |
| 323 | 317 | |
| @@ -36,9 +36,6 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <drm/drm_dp_mst_helper.h> |
| 37 | 37 | #include <drm/drm_rect.h> |
| 38 | 38 | |
| 39 | −#define DIV_ROUND_CLOSEST_ULL(ll, d) \ | |
| 40 | −({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | |
| 41 | − | |
| 42 | 39 | /** |
| 43 | 40 | * _wait_for - magic (register) wait macro |
| 44 | 41 | * |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 32 | 32 | |
| 33 | +#include <linux/kernel.h> | |
| 33 | 34 | #include <linux/moduleparam.h> |
| 34 | 35 | #include "intel_drv.h" |
| 35 | 36 | |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <linux/jiffies.h> |
| 37 | 37 | #include <linux/of.h> |
| 38 | 38 | #include <linux/delay.h> |
| 39 | +#include <linux/util_macros.h> | |
| 39 | 40 | |
| 40 | 41 | #include <linux/platform_data/ina2xx.h> |
| 41 | 42 | |
| @@ -141,19 +142,6 @@ static const struct ina2xx_config ina2xx_config[] = { · 99 unmodified lines | ||
| 141 | 142 | */ |
| 142 | 143 | static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 }; |
| 143 | 144 | |
| 144 | −static int ina226_avg_bits(int avg) | |
| 145 | −{ | |
| 146 | − int i; | |
| 147 | − | |
| 148 | − /* Get the closest average from the tab. */ | |
| 149 | − for (i = 0; i < ARRAY_SIZE(ina226_avg_tab) - 1; i++) { | |
| 150 | − if (avg <= (ina226_avg_tab[i] + ina226_avg_tab[i + 1]) / 2) | |
| 151 | − break; | |
| 152 | − } | |
| 153 | − | |
| 154 | − return i; /* Return 0b0111 for values greater than 1024. */ | |
| 155 | −} | |
| 156 | − | |
| 157 | 145 | static int ina226_reg_to_interval(u16 config) |
| 158 | 146 | { |
| 159 | 147 | int avg = ina226_avg_tab[INA226_READ_AVG(config)]; |
| @@ -171,7 +159,8 @@ static u16 ina226_interval_to_reg(int interval, u16 config) · 11 unmodified lines | ||
| 171 | 159 | |
| 172 | 160 | avg = DIV_ROUND_CLOSEST(interval * 1000, |
| 173 | 161 | INA226_TOTAL_CONV_TIME_DEFAULT); |
| 174 | − avg_bits = ina226_avg_bits(avg); | |
| 162 | + avg_bits = find_closest(avg, ina226_avg_tab, | |
| 163 | + ARRAY_SIZE(ina226_avg_tab)); | |
| 175 | 164 | |
| 176 | 165 | return (config & ~INA226_AVG_RD_MASK) | INA226_SHIFT_AVG(avg_bits); |
| 177 | 166 | } |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <linux/hwmon-sysfs.h> |
| 35 | 35 | #include <linux/err.h> |
| 36 | 36 | #include <linux/mutex.h> |
| 37 | +#include <linux/util_macros.h> | |
| 37 | 38 | |
| 38 | 39 | /* Addresses to scan */ |
| 39 | 40 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; |
| @@ -190,15 +191,7 @@ static const int lm85_range_map[] = { · 150 unmodified lines | ||
| 190 | 191 | |
| 191 | 192 | static int RANGE_TO_REG(long range) |
| 192 | 193 | { |
| 193 | − int i; | |
| 194 | − | |
| 195 | − /* Find the closest match */ | |
| 196 | − for (i = 0; i < 15; ++i) { | |
| 197 | − if (range <= (lm85_range_map[i] + lm85_range_map[i + 1]) / 2) | |
| 198 | − break; | |
| 199 | − } | |
| 200 | − | |
| 201 | − return i; | |
| 194 | + return find_closest(range, lm85_range_map, ARRAY_SIZE(lm85_range_map)); | |
| 202 | 195 | } |
| 203 | 196 | #define RANGE_FROM_REG(val) lm85_range_map[(val) & 0x0f] |
| 204 | 197 | |
| @@ -209,16 +202,12 @@ static const int lm85_freq_map[8] = { /* 1 Hz */ · 4 unmodified lines | ||
| 209 | 202 | static const int adm1027_freq_map[8] = { /* 1 Hz */ |
| 210 | 203 | 11, 15, 22, 29, 35, 44, 59, 88 |
| 211 | 204 | }; |
| 205 | +#define FREQ_MAP_LEN 8 | |
| 212 | 206 | |
| 213 | −static int FREQ_TO_REG(const int *map, unsigned long freq) | |
| 207 | +static int FREQ_TO_REG(const int *map, | |
| 208 | + unsigned int map_size, unsigned long freq) | |
| 214 | 209 | { |
| 215 | − int i; | |
| 216 | − | |
| 217 | − /* Find the closest match */ | |
| 218 | − for (i = 0; i < 7; ++i) | |
| 219 | − if (freq <= (map[i] + map[i + 1]) / 2) | |
| 220 | − break; | |
| 221 | − return i; | |
| 210 | + return find_closest(freq, map, map_size); | |
| 222 | 211 | } |
| 223 | 212 | |
| 224 | 213 | static int FREQ_FROM_REG(const int *map, u8 reg) |
| @@ -828,7 +817,8 @@ static ssize_t set_pwm_freq(struct device *dev, · 603 unmodified lines | ||
| 828 | 817 | data->cfg5 &= ~ADT7468_HFPWM; |
| 829 | 818 | lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5); |
| 830 | 819 | } else { /* Low freq. mode */ |
| 831 | − data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val); | |
| 820 | + data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, | |
| 821 | + FREQ_MAP_LEN, val); | |
| 832 | 822 | lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), |
| 833 | 823 | (data->zone[nr].range << 4) |
| 834 | 824 | | data->pwm_freq[nr]); |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <linux/err.h> |
| 36 | 36 | #include <linux/mutex.h> |
| 37 | 37 | #include <linux/jiffies.h> |
| 38 | +#include <linux/util_macros.h> | |
| 38 | 39 | |
| 39 | 40 | /* Addresses to scan */ |
| 40 | 41 | static const unsigned short normal_i2c[] = { |
| @@ -308,11 +309,8 @@ static u8 pwm_freq_to_reg(unsigned long val, u16 clkin) · 267 unmodified lines | ||
| 308 | 309 | unsigned long best0, best1; |
| 309 | 310 | |
| 310 | 311 | /* Best fit for cksel = 0 */ |
| 311 | − for (reg0 = 0; reg0 < ARRAY_SIZE(pwm_freq_cksel0) - 1; reg0++) { | |
| 312 | − if (val > (pwm_freq_cksel0[reg0] + | |
| 313 | − pwm_freq_cksel0[reg0 + 1]) / 2) | |
| 314 | − break; | |
| 315 | − } | |
| 312 | + reg0 = find_closest_descending(val, pwm_freq_cksel0, | |
| 313 | + ARRAY_SIZE(pwm_freq_cksel0)); | |
| 316 | 314 | if (val < 375) /* cksel = 1 can't beat this */ |
| 317 | 315 | return reg0; |
| 318 | 316 | best0 = pwm_freq_cksel0[reg0]; |
| @@ -79,7 +79,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe) · 78 unmodified lines | ||
| 79 | 79 | |
| 80 | 80 | num = if_freq / 1000; /* Hz => kHz */ |
| 81 | 81 | num *= 0x4000; |
| 82 | − if_ctl = 0x4000 - cxd2820r_div_u64_round_closest(num, 41000); | |
| 82 | + if_ctl = 0x4000 - DIV_ROUND_CLOSEST_ULL(num, 41000); | |
| 83 | 83 | buf[0] = (if_ctl >> 8) & 0x3f; |
| 84 | 84 | buf[1] = (if_ctl >> 0) & 0xff; |
| 85 | 85 | |
| @@ -244,12 +244,6 @@ error: · 243 unmodified lines | ||
| 244 | 244 | return ret; |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | −/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */ | |
| 248 | −u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor) | |
| 249 | −{ | |
| 250 | − return div_u64(dividend + (divisor / 2), divisor); | |
| 251 | −} | |
| 252 | − | |
| 253 | 247 | static int cxd2820r_set_frontend(struct dvb_frontend *fe) |
| 254 | 248 | { |
| 255 | 249 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
| @@ -64,8 +64,6 @@ int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, · 63 unmodified lines | ||
| 64 | 64 | int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val, |
| 65 | 65 | int len); |
| 66 | 66 | |
| 67 | −u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor); | |
| 68 | − | |
| 69 | 67 | int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val, |
| 70 | 68 | int len); |
| 71 | 69 | |
| @@ -103,7 +103,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe) · 102 unmodified lines | ||
| 103 | 103 | |
| 104 | 104 | num = if_freq / 1000; /* Hz => kHz */ |
| 105 | 105 | num *= 0x1000000; |
| 106 | − if_ctl = cxd2820r_div_u64_round_closest(num, 41000); | |
| 106 | + if_ctl = DIV_ROUND_CLOSEST_ULL(num, 41000); | |
| 107 | 107 | buf[0] = ((if_ctl >> 16) & 0xff); |
| 108 | 108 | buf[1] = ((if_ctl >> 8) & 0xff); |
| 109 | 109 | buf[2] = ((if_ctl >> 0) & 0xff); |
| @@ -120,7 +120,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | num = if_freq / 1000; /* Hz => kHz */ |
| 122 | 122 | num *= 0x1000000; |
| 123 | − if_ctl = cxd2820r_div_u64_round_closest(num, 41000); | |
| 123 | + if_ctl = DIV_ROUND_CLOSEST_ULL(num, 41000); | |
| 124 | 124 | buf[0] = ((if_ctl >> 16) & 0xff); |
| 125 | 125 | buf[1] = ((if_ctl >> 8) & 0xff); |
| 126 | 126 | buf[2] = ((if_ctl >> 0) & 0xff); |
| @@ -758,7 +758,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error) · 757 unmodified lines | ||
| 758 | 758 | |
| 759 | 759 | if (error || (card->current_mrq.tpc == MSPRO_CMD_STOP)) { |
| 760 | 760 | if (msb->data_dir == READ) { |
| 761 | − for (cnt = 0; cnt < msb->current_seg; cnt++) | |
| 761 | + for (cnt = 0; cnt < msb->current_seg; cnt++) { | |
| 762 | 762 | t_len += msb->req_sg[cnt].length |
| 763 | 763 | / msb->page_size; |
| 764 | 764 | |
| @@ -766,6 +766,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error) · 1 unmodified line | ||
| 766 | 766 | t_len += msb->current_page - 1; |
| 767 | 767 | |
| 768 | 768 | t_len *= msb->page_size; |
| 769 | + } | |
| 769 | 770 | } |
| 770 | 771 | } else |
| 771 | 772 | t_len = blk_rq_bytes(msb->block_req); |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | * objects. |
| 22 | 22 | */ |
| 23 | 23 | |
| 24 | +#include <linux/file.h> | |
| 24 | 25 | #include <linux/mm.h> |
| 25 | 26 | #include <linux/workqueue.h> |
| 26 | 27 | #include <linux/notifier.h> |
| @@ -224,10 +225,18 @@ static inline unsigned long fast_get_dcookie(struct path *path) · 197 unmodified lines | ||
| 224 | 225 | static unsigned long get_exec_dcookie(struct mm_struct *mm) |
| 225 | 226 | { |
| 226 | 227 | unsigned long cookie = NO_COOKIE; |
| 228 | + struct file *exe_file; | |
| 227 | 229 | |
| 228 | − if (mm && mm->exe_file) | |
| 229 | − cookie = fast_get_dcookie(&mm->exe_file->f_path); | |
| 230 | + if (!mm) | |
| 231 | + goto done; | |
| 232 | + | |
| 233 | + exe_file = get_mm_exe_file(mm); | |
| 234 | + if (!exe_file) | |
| 235 | + goto done; | |
| 230 | 236 | |
| 237 | + cookie = fast_get_dcookie(&exe_file->f_path); | |
| 238 | + fput(exe_file); | |
| 239 | +done: | |
| 231 | 240 | return cookie; |
| 232 | 241 | } |
| 233 | 242 | |
| @@ -236,6 +245,8 @@ static unsigned long get_exec_dcookie(struct mm_struct *mm) · 2 unmodified lines | ||
| 236 | 245 | * pair that can then be added to the global event buffer. We make |
| 237 | 246 | * sure to do this lookup before a mm->mmap modification happens so |
| 238 | 247 | * we don't lose track. |
| 248 | + * | |
| 249 | + * The caller must ensure the mm is not nil (ie: not a kernel thread). | |
| 239 | 250 | */ |
| 240 | 251 | static unsigned long |
| 241 | 252 | 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) · 1 unmodified line | ||
| 243 | 254 | unsigned long cookie = NO_COOKIE; |
| 244 | 255 | struct vm_area_struct *vma; |
| 245 | 256 | |
| 257 | + down_read(&mm->mmap_sem); | |
| 246 | 258 | for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { |
| 247 | 259 | |
| 248 | 260 | 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) · 13 unmodified lines | ||
| 262 | 274 | |
| 263 | 275 | if (!vma) |
| 264 | 276 | cookie = INVALID_COOKIE; |
| 277 | + up_read(&mm->mmap_sem); | |
| 265 | 278 | |
| 266 | 279 | return cookie; |
| 267 | 280 | } |
| @@ -402,20 +415,9 @@ static void release_mm(struct mm_struct *mm) · 134 unmodified lines | ||
| 402 | 415 | { |
| 403 | 416 | if (!mm) |
| 404 | 417 | return; |
| 405 | − up_read(&mm->mmap_sem); | |
| 406 | 418 | mmput(mm); |
| 407 | 419 | } |
| 408 | 420 | |
| 409 | − | |
| 410 | −static struct mm_struct *take_tasks_mm(struct task_struct *task) | |
| 411 | −{ | |
| 412 | − struct mm_struct *mm = get_task_mm(task); | |
| 413 | − if (mm) | |
| 414 | − down_read(&mm->mmap_sem); | |
| 415 | − return mm; | |
| 416 | −} | |
| 417 | − | |
| 418 | − | |
| 419 | 421 | static inline int is_code(unsigned long val) |
| 420 | 422 | { |
| 421 | 423 | return val == ESCAPE_CODE; |
| @@ -532,7 +534,7 @@ void sync_buffer(int cpu) · 110 unmodified lines | ||
| 532 | 534 | new = (struct task_struct *)val; |
| 533 | 535 | oldmm = mm; |
| 534 | 536 | release_mm(oldmm); |
| 535 | − mm = take_tasks_mm(new); | |
| 537 | + mm = get_task_mm(new); | |
| 536 | 538 | if (mm != oldmm) |
| 537 | 539 | cookie = get_exec_dcookie(mm); |
| 538 | 540 | add_user_ctx_switch(new, cookie); |
| @@ -1111,6 +1111,16 @@ config RTC_DRV_DAVINCI · 1110 unmodified lines | ||
| 1111 | 1111 | This driver can also be built as a module. If so, the module |
| 1112 | 1112 | will be called rtc-davinci. |
| 1113 | 1113 | |
| 1114 | +config RTC_DRV_DIGICOLOR | |
| 1115 | + tristate "Conexant Digicolor RTC" | |
| 1116 | + depends on ARCH_DIGICOLOR | |
| 1117 | + help | |
| 1118 | + If you say yes here you get support for the RTC on Conexant | |
| 1119 | + Digicolor platforms. This currently includes the CX92755 SoC. | |
| 1120 | + | |
| 1121 | + This driver can also be built as a module. If so, the module | |
| 1122 | + will be called rtc-digicolor. | |
| 1123 | + | |
| 1114 | 1124 | config RTC_DRV_IMXDI |
| 1115 | 1125 | tristate "Freescale IMX DryIce Real Time Clock" |
| 1116 | 1126 | depends on ARCH_MXC |
| @@ -1121,11 +1131,11 @@ config RTC_DRV_IMXDI · 4 unmodified lines | ||
| 1121 | 1131 | will be called "rtc-imxdi". |
| 1122 | 1132 | |
| 1123 | 1133 | config RTC_DRV_OMAP |
| 1124 | − tristate "TI OMAP1" | |
| 1125 | − depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX || SOC_AM33XX | |
| 1134 | + tristate "TI OMAP Real Time Clock" | |
| 1135 | + depends on ARCH_OMAP || ARCH_DAVINCI | |
| 1126 | 1136 | help |
| 1127 | 1137 | Say "yes" here to support the on chip real time clock |
| 1128 | − present on TI OMAP1, AM33xx and DA8xx/OMAP-L13x. | |
| 1138 | + present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx. | |
| 1129 | 1139 | |
| 1130 | 1140 | This driver can also be built as a module, if so, module |
| 1131 | 1141 | will be called rtc-omap. |
| @@ -40,6 +40,7 @@ obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o · 39 unmodified lines | ||
| 40 | 40 | obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o |
| 41 | 41 | obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o |
| 42 | 42 | obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o |
| 43 | +obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o | |
| 43 | 44 | obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o |
| 44 | 45 | obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o |
| 45 | 46 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
| @@ -221,15 +221,15 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, · 220 unmodified lines | ||
| 221 | 221 | rtc->pie_timer.function = rtc_pie_update_irq; |
| 222 | 222 | rtc->pie_enabled = 0; |
| 223 | 223 | |
| 224 | + strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); | |
| 225 | + dev_set_name(&rtc->dev, "rtc%d", id); | |
| 226 | + | |
| 224 | 227 | /* Check to see if there is an ALARM already set in hw */ |
| 225 | 228 | err = __rtc_read_alarm(rtc, &alrm); |
| 226 | 229 | |
| 227 | 230 | if (!err && !rtc_valid_tm(&alrm.time)) |
| 228 | 231 | rtc_initialize_alarm(rtc, &alrm); |
| 229 | 232 | |
| 230 | − strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); | |
| 231 | − dev_set_name(&rtc->dev, "rtc%d", id); | |
| 232 | − | |
| 233 | 233 | rtc_dev_prepare(rtc); |
| 234 | 234 | |
| 235 | 235 | err = device_register(&rtc->dev); |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | * published by the Free Software Foundation. |
| 10 | 10 | */ |
| 11 | 11 | |
| 12 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 13 | + | |
| 12 | 14 | #include <linux/rtc.h> |
| 13 | 15 | |
| 14 | 16 | /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary |
| @@ -32,8 +34,8 @@ static int __init rtc_hctosys(void) · 17 unmodified lines | ||
| 32 | 34 | struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); |
| 33 | 35 | |
| 34 | 36 | if (rtc == NULL) { |
| 35 | − pr_err("%s: unable to open rtc device (%s)\n", | |
| 36 | − __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); | |
| 37 | + pr_info("unable to open rtc device (%s)\n", | |
| 38 | + CONFIG_RTC_HCTOSYS_DEVICE); | |
| 37 | 39 | goto err_open; |
| 38 | 40 | } |
| 39 | 41 | |
| @@ -31,13 +31,14 @@ static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) · 30 unmodified lines | ||
| 31 | 31 | memset(tm, 0, sizeof(struct rtc_time)); |
| 32 | 32 | err = rtc->ops->read_time(rtc->dev.parent, tm); |
| 33 | 33 | if (err < 0) { |
| 34 | − dev_err(&rtc->dev, "read_time: fail to read\n"); | |
| 34 | + dev_dbg(&rtc->dev, "read_time: fail to read: %d\n", | |
| 35 | + err); | |
| 35 | 36 | return err; |
| 36 | 37 | } |
| 37 | 38 | |
| 38 | 39 | err = rtc_valid_tm(tm); |
| 39 | 40 | if (err < 0) |
| 40 | − dev_err(&rtc->dev, "read_time: rtc_time isn't valid\n"); | |
| 41 | + dev_dbg(&rtc->dev, "read_time: rtc_time isn't valid\n"); | |
| 41 | 42 | } |
| 42 | 43 | return err; |
| 43 | 44 | } |
| @@ -881,7 +881,7 @@ static const struct rtc_class_ops rtc_ops = { · 880 unmodified lines | ||
| 881 | 881 | .alarm_irq_enable = abb5zes3_rtc_alarm_irq_enable, |
| 882 | 882 | }; |
| 883 | 883 | |
| 884 | −static struct regmap_config abb5zes3_rtc_regmap_config = { | |
| 884 | +static const struct regmap_config abb5zes3_rtc_regmap_config = { | |
| 885 | 885 | .reg_bits = 8, |
| 886 | 886 | .val_bits = 8, |
| 887 | 887 | }; |
| @@ -37,9 +37,9 @@ · 36 unmodified lines | ||
| 37 | 37 | #include "rtc-at91rm9200.h" |
| 38 | 38 | |
| 39 | 39 | #define at91_rtc_read(field) \ |
| 40 | − __raw_readl(at91_rtc_regs + field) | |
| 40 | + readl_relaxed(at91_rtc_regs + field) | |
| 41 | 41 | #define at91_rtc_write(field, val) \ |
| 42 | − __raw_writel((val), at91_rtc_regs + field) | |
| 42 | + writel_relaxed((val), at91_rtc_regs + field) | |
| 43 | 43 | |
| 44 | 44 | #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ |
| 45 | 45 | |
| @@ -28,6 +28,9 @@ · 27 unmodified lines | ||
| 28 | 28 | * interrupts disabled, holding the global rtc_lock, to exclude those |
| 29 | 29 | * other drivers and utilities on correctly configured systems. |
| 30 | 30 | */ |
| 31 | + | |
| 32 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 33 | + | |
| 31 | 34 | #include <linux/kernel.h> |
| 32 | 35 | #include <linux/module.h> |
| 33 | 36 | #include <linux/init.h> |
| @@ -385,8 +388,7 @@ static bool alarm_disable_quirk; · 351 unmodified lines | ||
| 385 | 388 | static int __init set_alarm_disable_quirk(const struct dmi_system_id *id) |
| 386 | 389 | { |
| 387 | 390 | alarm_disable_quirk = true; |
| 388 | − pr_info("rtc-cmos: BIOS has alarm-disable quirk. "); | |
| 389 | − pr_info("RTC alarms disabled\n"); | |
| 391 | + pr_info("BIOS has alarm-disable quirk - RTC alarms disabled\n"); | |
| 390 | 392 | return 0; |
| 391 | 393 | } |
| 392 | 394 | |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/platform_device.h> |
| 17 | 17 | #include <linux/rtc.h> |
| 18 | 18 | #include <linux/err.h> |
| 19 | +#include <linux/delay.h> | |
| 19 | 20 | |
| 20 | 21 | #include <linux/mfd/da9052/da9052.h> |
| 21 | 22 | #include <linux/mfd/da9052/reg.h> |
| @@ -23,6 +24,8 @@ · 1 unmodified line | ||
| 23 | 24 | #define rtc_err(rtc, fmt, ...) \ |
| 24 | 25 | dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__) |
| 25 | 26 | |
| 27 | +#define DA9052_GET_TIME_RETRIES 5 | |
| 28 | + | |
| 26 | 29 | struct da9052_rtc { |
| 27 | 30 | struct rtc_device *rtc; |
| 28 | 31 | struct da9052 *da9052; |
| @@ -58,22 +61,43 @@ static irqreturn_t da9052_rtc_irq(int irq, void *data) · 29 unmodified lines | ||
| 58 | 61 | static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) |
| 59 | 62 | { |
| 60 | 63 | int ret; |
| 61 | − uint8_t v[5]; | |
| 64 | + uint8_t v[2][5]; | |
| 65 | + int idx = 1; | |
| 66 | + int timeout = DA9052_GET_TIME_RETRIES; | |
| 62 | 67 | |
| 63 | − ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, v); | |
| 64 | − if (ret != 0) { | |
| 68 | + ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, &v[0][0]); | |
| 69 | + if (ret) { | |
| 65 | 70 | rtc_err(rtc, "Failed to group read ALM: %d\n", ret); |
| 66 | 71 | return ret; |
| 67 | 72 | } |
| 68 | 73 | |
| 69 | − rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100; | |
| 70 | − rtc_tm->tm_mon = (v[3] & DA9052_RTC_MONTH) - 1; | |
| 71 | − rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY; | |
| 72 | − rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR; | |
| 73 | − rtc_tm->tm_min = v[0] & DA9052_RTC_MIN; | |
| 74 | + do { | |
| 75 | + ret = da9052_group_read(rtc->da9052, | |
| 76 | + DA9052_ALARM_MI_REG, 5, &v[idx][0]); | |
| 77 | + if (ret) { | |
| 78 | + rtc_err(rtc, "Failed to group read ALM: %d\n", ret); | |
| 79 | + return ret; | |
| 80 | + } | |
| 74 | 81 | |
| 75 | − ret = rtc_valid_tm(rtc_tm); | |
| 76 | − return ret; | |
| 82 | + if (memcmp(&v[0][0], &v[1][0], 5) == 0) { | |
| 83 | + rtc_tm->tm_year = (v[0][4] & DA9052_RTC_YEAR) + 100; | |
| 84 | + rtc_tm->tm_mon = (v[0][3] & DA9052_RTC_MONTH) - 1; | |
| 85 | + rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY; | |
| 86 | + rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR; | |
| 87 | + rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN; | |
| 88 | + | |
| 89 | + ret = rtc_valid_tm(rtc_tm); | |
| 90 | + return ret; | |
| 91 | + } | |
| 92 | + | |
| 93 | + idx = (1-idx); | |
| 94 | + msleep(20); | |
| 95 | + | |
| 96 | + } while (timeout--); | |
| 97 | + | |
| 98 | + rtc_err(rtc, "Timed out reading alarm time\n"); | |
| 99 | + | |
| 100 | + return -EIO; | |
| 77 | 101 | } |
| 78 | 102 | |
| 79 | 103 | 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) · 55 unmodified lines | ||
| 135 | 159 | static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) |
| 136 | 160 | { |
| 137 | 161 | struct da9052_rtc *rtc = dev_get_drvdata(dev); |
| 138 | − uint8_t v[6]; | |
| 139 | 162 | int ret; |
| 163 | + uint8_t v[2][6]; | |
| 164 | + int idx = 1; | |
| 165 | + int timeout = DA9052_GET_TIME_RETRIES; | |
| 140 | 166 | |
| 141 | − ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v); | |
| 142 | − if (ret < 0) { | |
| 167 | + ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, &v[0][0]); | |
| 168 | + if (ret) { | |
| 143 | 169 | rtc_err(rtc, "Failed to read RTC time : %d\n", ret); |
| 144 | 170 | return ret; |
| 145 | 171 | } |
| 146 | 172 | |
| 147 | − rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100; | |
| 148 | − rtc_tm->tm_mon = (v[4] & DA9052_RTC_MONTH) - 1; | |
| 149 | − rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY; | |
| 150 | − rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR; | |
| 151 | − rtc_tm->tm_min = v[1] & DA9052_RTC_MIN; | |
| 152 | − rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC; | |
| 173 | + do { | |
| 174 | + ret = da9052_group_read(rtc->da9052, | |
| 175 | + DA9052_COUNT_S_REG, 6, &v[idx][0]); | |
| 176 | + if (ret) { | |
| 177 | + rtc_err(rtc, "Failed to read RTC time : %d\n", ret); | |
| 178 | + return ret; | |
| 179 | + } | |
| 153 | 180 | |
| 154 | − ret = rtc_valid_tm(rtc_tm); | |
| 155 | − return ret; | |
| 181 | + if (memcmp(&v[0][0], &v[1][0], 6) == 0) { | |
| 182 | + rtc_tm->tm_year = (v[0][5] & DA9052_RTC_YEAR) + 100; | |
| 183 | + rtc_tm->tm_mon = (v[0][4] & DA9052_RTC_MONTH) - 1; | |
| 184 | + rtc_tm->tm_mday = v[0][3] & DA9052_RTC_DAY; | |
| 185 | + rtc_tm->tm_hour = v[0][2] & DA9052_RTC_HOUR; | |
| 186 | + rtc_tm->tm_min = v[0][1] & DA9052_RTC_MIN; | |
| 187 | + rtc_tm->tm_sec = v[0][0] & DA9052_RTC_SEC; | |
| 188 | + | |
| 189 | + ret = rtc_valid_tm(rtc_tm); | |
| 190 | + return ret; | |
| 191 | + } | |
| 192 | + | |
| 193 | + idx = (1-idx); | |
| 194 | + msleep(20); | |
| 195 | + | |
| 196 | + } while (timeout--); | |
| 197 | + | |
| 198 | + rtc_err(rtc, "Timed out reading time\n"); | |
| 199 | + | |
| 200 | + return -EIO; | |
| 156 | 201 | } |
| 157 | 202 | |
| 158 | 203 | 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) · 2 unmodified lines | ||
| 161 | 206 | uint8_t v[6]; |
| 162 | 207 | int ret; |
| 163 | 208 | |
| 209 | + /* DA9052 only has 6 bits for year - to represent 2000-2063 */ | |
| 210 | + if ((tm->tm_year < 100) || (tm->tm_year > 163)) | |
| 211 | + return -EINVAL; | |
| 212 | + | |
| 164 | 213 | rtc = dev_get_drvdata(dev); |
| 165 | 214 | |
| 166 | 215 | v[0] = tm->tm_sec; |
| @@ -198,6 +247,10 @@ static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) · 31 unmodified lines | ||
| 198 | 247 | struct rtc_time *tm = &alrm->time; |
| 199 | 248 | struct da9052_rtc *rtc = dev_get_drvdata(dev); |
| 200 | 249 | |
| 250 | + /* DA9052 only has 6 bits for year - to represent 2000-2063 */ | |
| 251 | + if ((tm->tm_year < 100) || (tm->tm_year > 163)) | |
| 252 | + return -EINVAL; | |
| 253 | + | |
| 201 | 254 | ret = da9052_rtc_enable_alarm(rtc, 0); |
| 202 | 255 | if (ret < 0) |
| 203 | 256 | return ret; |
| @@ -256,6 +309,8 @@ static int da9052_rtc_probe(struct platform_device *pdev) · 52 unmodified lines | ||
| 256 | 309 | return ret; |
| 257 | 310 | } |
| 258 | 311 | |
| 312 | + device_init_wakeup(&pdev->dev, true); | |
| 313 | + | |
| 259 | 314 | rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, |
| 260 | 315 | &da9052_rtc_ops, THIS_MODULE); |
| 261 | 316 | return PTR_ERR_OR_ZERO(rtc->rtc); |
| @@ -0,0 +1,227 @@ | ||
| 1 | +/* | |
| 2 | + * Real Time Clock driver for Conexant Digicolor | |
| 3 | + * | |
| 4 | + * Copyright (C) 2015 Paradox Innovation Ltd. | |
| 5 | + * | |
| 6 | + * Author: Baruch Siach <baruch@tkos.co.il> | |
| 7 | + * | |
| 8 | + * This program is free software; you can redistribute it and/or modify it | |
| 9 | + * under the terms of the GNU General Public License as published by the | |
| 10 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 11 | + * option) any later version. | |
| 12 | + */ | |
| 13 | + | |
| 14 | +#include <linux/io.h> | |
| 15 | +#include <linux/iopoll.h> | |
| 16 | +#include <linux/delay.h> | |
| 17 | +#include <linux/module.h> | |
| 18 | +#include <linux/platform_device.h> | |
| 19 | +#include <linux/rtc.h> | |
| 20 | +#include <linux/of.h> | |
| 21 | + | |
| 22 | +#define DC_RTC_CONTROL 0x0 | |
| 23 | +#define DC_RTC_TIME 0x8 | |
| 24 | +#define DC_RTC_REFERENCE 0xc | |
| 25 | +#define DC_RTC_ALARM 0x10 | |
| 26 | +#define DC_RTC_INTFLAG_CLEAR 0x14 | |
| 27 | +#define DC_RTC_INTENABLE 0x16 | |
| 28 | + | |
| 29 | +#define DC_RTC_CMD_MASK 0xf | |
| 30 | +#define DC_RTC_GO_BUSY BIT(7) | |
| 31 | + | |
| 32 | +#define CMD_NOP 0 | |
| 33 | +#define CMD_RESET 1 | |
| 34 | +#define CMD_WRITE 3 | |
| 35 | +#define CMD_READ 4 | |
| 36 | + | |
| 37 | +#define CMD_DELAY_US (10*1000) | |
| 38 | +#define CMD_TIMEOUT_US (500*CMD_DELAY_US) | |
| 39 | + | |
| 40 | +struct dc_rtc { | |
| 41 | + struct rtc_device *rtc_dev; | |
| 42 | + void __iomem *regs; | |
| 43 | +}; | |
| 44 | + | |
| 45 | +static int dc_rtc_cmds(struct dc_rtc *rtc, const u8 *cmds, int len) | |
| 46 | +{ | |
| 47 | + u8 val; | |
| 48 | + int i, ret; | |
| 49 | + | |
| 50 | + for (i = 0; i < len; i++) { | |
| 51 | + writeb_relaxed((cmds[i] & DC_RTC_CMD_MASK) | DC_RTC_GO_BUSY, | |
| 52 | + rtc->regs + DC_RTC_CONTROL); | |
| 53 | + ret = readb_relaxed_poll_timeout( | |
| 54 | + rtc->regs + DC_RTC_CONTROL, val, | |
| 55 | + !(val & DC_RTC_GO_BUSY), CMD_DELAY_US, CMD_TIMEOUT_US); | |
| 56 | + if (ret < 0) | |
| 57 | + return ret; | |
| 58 | + } | |
| 59 | + | |
| 60 | + return 0; | |
| 61 | +} | |
| 62 | + | |
| 63 | +static int dc_rtc_read(struct dc_rtc *rtc, unsigned long *val) | |
| 64 | +{ | |
| 65 | + static const u8 read_cmds[] = {CMD_READ, CMD_NOP}; | |
| 66 | + u32 reference, time1, time2; | |
| 67 | + int ret; | |
| 68 | + | |
| 69 | + ret = dc_rtc_cmds(rtc, read_cmds, ARRAY_SIZE(read_cmds)); | |
| 70 | + if (ret < 0) | |
| 71 | + return ret; | |
| 72 | + | |
| 73 | + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); | |
| 74 | + time1 = readl_relaxed(rtc->regs + DC_RTC_TIME); | |
| 75 | + /* Read twice to ensure consistency */ | |
| 76 | + while (1) { | |
| 77 | + time2 = readl_relaxed(rtc->regs + DC_RTC_TIME); | |
| 78 | + if (time1 == time2) | |
| 79 | + break; | |
| 80 | + time1 = time2; | |
| 81 | + } | |
| 82 | + | |
| 83 | + *val = reference + time1; | |
| 84 | + return 0; | |
| 85 | +} | |
| 86 | + | |
| 87 | +static int dc_rtc_write(struct dc_rtc *rtc, u32 val) | |
| 88 | +{ | |
| 89 | + static const u8 write_cmds[] = {CMD_WRITE, CMD_NOP, CMD_RESET, CMD_NOP}; | |
| 90 | + | |
| 91 | + writel_relaxed(val, rtc->regs + DC_RTC_REFERENCE); | |
| 92 | + return dc_rtc_cmds(rtc, write_cmds, ARRAY_SIZE(write_cmds)); | |
| 93 | +} | |
| 94 | + | |
| 95 | +static int dc_rtc_read_time(struct device *dev, struct rtc_time *tm) | |
| 96 | +{ | |
| 97 | + struct dc_rtc *rtc = dev_get_drvdata(dev); | |
| 98 | + unsigned long now; | |
| 99 | + int ret; | |
| 100 | + | |
| 101 | + ret = dc_rtc_read(rtc, &now); | |
| 102 | + if (ret < 0) | |
| 103 | + return ret; | |
| 104 | + rtc_time64_to_tm(now, tm); | |
| 105 | + | |
| 106 | + return 0; | |
| 107 | +} | |
| 108 | + | |
| 109 | +static int dc_rtc_set_mmss(struct device *dev, unsigned long secs) | |
| 110 | +{ | |
| 111 | + struct dc_rtc *rtc = dev_get_drvdata(dev); | |
| 112 | + | |
| 113 | + return dc_rtc_write(rtc, secs); | |
| 114 | +} | |
| 115 | + | |
| 116 | +static int dc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |
| 117 | +{ | |
| 118 | + struct dc_rtc *rtc = dev_get_drvdata(dev); | |
| 119 | + u32 alarm_reg, reference; | |
| 120 | + unsigned long now; | |
| 121 | + int ret; | |
| 122 | + | |
| 123 | + alarm_reg = readl_relaxed(rtc->regs + DC_RTC_ALARM); | |
| 124 | + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); | |
| 125 | + rtc_time64_to_tm(reference + alarm_reg, &alarm->time); | |
| 126 | + | |
| 127 | + ret = dc_rtc_read(rtc, &now); | |
| 128 | + if (ret < 0) | |
| 129 | + return ret; | |
| 130 | + | |
| 131 | + alarm->pending = alarm_reg + reference > now; | |
| 132 | + alarm->enabled = readl_relaxed(rtc->regs + DC_RTC_INTENABLE); | |
| 133 | + | |
| 134 | + return 0; | |
| 135 | +} | |
| 136 | + | |
| 137 | +static int dc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |
| 138 | +{ | |
| 139 | + struct dc_rtc *rtc = dev_get_drvdata(dev); | |
| 140 | + time64_t alarm_time; | |
| 141 | + u32 reference; | |
| 142 | + | |
| 143 | + alarm_time = rtc_tm_to_time64(&alarm->time); | |
| 144 | + | |
| 145 | + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); | |
| 146 | + writel_relaxed(alarm_time - reference, rtc->regs + DC_RTC_ALARM); | |
| 147 | + | |
| 148 | + writeb_relaxed(!!alarm->enabled, rtc->regs + DC_RTC_INTENABLE); | |
| 149 | + | |
| 150 | + return 0; | |
| 151 | +} | |
| 152 | + | |
| 153 | +static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |
| 154 | +{ | |
| 155 | + struct dc_rtc *rtc = dev_get_drvdata(dev); | |
| 156 | + | |
| 157 | + writeb_relaxed(!!enabled, rtc->regs + DC_RTC_INTENABLE); | |
| 158 | + | |
| 159 | + return 0; | |
| 160 | +} | |
| 161 | + | |
| 162 | +static struct rtc_class_ops dc_rtc_ops = { | |
| 163 | + .read_time = dc_rtc_read_time, | |
| 164 | + .set_mmss = dc_rtc_set_mmss, | |
| 165 | + .read_alarm = dc_rtc_read_alarm, | |
| 166 | + .set_alarm = dc_rtc_set_alarm, | |
| 167 | + .alarm_irq_enable = dc_rtc_alarm_irq_enable, | |
| 168 | +}; | |
| 169 | + | |
| 170 | +static irqreturn_t dc_rtc_irq(int irq, void *dev_id) | |
| 171 | +{ | |
| 172 | + struct dc_rtc *rtc = dev_id; | |
| 173 | + | |
| 174 | + writeb_relaxed(1, rtc->regs + DC_RTC_INTFLAG_CLEAR); | |
| 175 | + rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); | |
| 176 | + | |
| 177 | + return IRQ_HANDLED; | |
| 178 | +} | |
| 179 | + | |
| 180 | +static int __init dc_rtc_probe(struct platform_device *pdev) | |
| 181 | +{ | |
| 182 | + struct resource *res; | |
| 183 | + struct dc_rtc *rtc; | |
| 184 | + int irq, ret; | |
| 185 | + | |
| 186 | + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | |
| 187 | + if (!rtc) | |
| 188 | + return -ENOMEM; | |
| 189 | + | |
| 190 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 191 | + rtc->regs = devm_ioremap_resource(&pdev->dev, res); | |
| 192 | + if (IS_ERR(rtc->regs)) | |
| 193 | + return PTR_ERR(rtc->regs); | |
| 194 | + | |
| 195 | + irq = platform_get_irq(pdev, 0); | |
| 196 | + if (irq < 0) | |
| 197 | + return irq; | |
| 198 | + ret = devm_request_irq(&pdev->dev, irq, dc_rtc_irq, 0, pdev->name, rtc); | |
| 199 | + if (ret < 0) | |
| 200 | + return ret; | |
| 201 | + | |
| 202 | + platform_set_drvdata(pdev, rtc); | |
| 203 | + rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, | |
| 204 | + &dc_rtc_ops, THIS_MODULE); | |
| 205 | + if (IS_ERR(rtc->rtc_dev)) | |
| 206 | + return PTR_ERR(rtc->rtc_dev); | |
| 207 | + | |
| 208 | + return 0; | |
| 209 | +} | |
| 210 | + | |
| 211 | +static const struct of_device_id dc_dt_ids[] = { | |
| 212 | + { .compatible = "cnxt,cx92755-rtc" }, | |
| 213 | + { /* sentinel */ } | |
| 214 | +}; | |
| 215 | +MODULE_DEVICE_TABLE(of, dc_dt_ids); | |
| 216 | + | |
| 217 | +static struct platform_driver dc_rtc_driver = { | |
| 218 | + .driver = { | |
| 219 | + .name = "digicolor_rtc", | |
| 220 | + .of_match_table = of_match_ptr(dc_dt_ids), | |
| 221 | + }, | |
| 222 | +}; | |
| 223 | +module_platform_driver_probe(dc_rtc_driver, dc_rtc_probe); | |
| 224 | + | |
| 225 | +MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); | |
| 226 | +MODULE_DESCRIPTION("Conexant Digicolor Realtime Clock Driver (RTC)"); | |
| 227 | +MODULE_LICENSE("GPL"); | |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | ||
| 18 | 18 | * "Sending and receiving", using SMBus level communication is preferred. |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 22 | + | |
| 21 | 23 | #include <linux/kernel.h> |
| 22 | 24 | #include <linux/module.h> |
| 23 | 25 | #include <linux/interrupt.h> |
| @@ -406,7 +408,7 @@ static int ds1374_wdt_settimeout(unsigned int timeout) · 382 unmodified lines | ||
| 406 | 408 | /* Set new watchdog time */ |
| 407 | 409 | ret = ds1374_write_rtc(save_client, timeout, DS1374_REG_WDALM0, 3); |
| 408 | 410 | if (ret) { |
| 409 | − pr_info("rtc-ds1374 - couldn't set new watchdog time\n"); | |
| 411 | + pr_info("couldn't set new watchdog time\n"); | |
| 410 | 412 | goto out; |
| 411 | 413 | } |
| 412 | 414 | |
| @@ -539,12 +541,12 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd, · 126 unmodified lines | ||
| 539 | 541 | return -EFAULT; |
| 540 | 542 | |
| 541 | 543 | if (options & WDIOS_DISABLECARD) { |
| 542 | − pr_info("rtc-ds1374: disable watchdog\n"); | |
| 544 | + pr_info("disable watchdog\n"); | |
| 543 | 545 | ds1374_wdt_disable(); |
| 544 | 546 | } |
| 545 | 547 | |
| 546 | 548 | if (options & WDIOS_ENABLECARD) { |
| 547 | − pr_info("rtc-ds1374: enable watchdog\n"); | |
| 549 | + pr_info("enable watchdog\n"); | |
| 548 | 550 | ds1374_wdt_settimeout(wdt_margin); |
| 549 | 551 | ds1374_wdt_ping(); |
| 550 | 552 | } |
| @@ -16,6 +16,8 @@ · 15 unmodified lines | ||
| 16 | 16 | * published by the Free Software Foundation. |
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 20 | + | |
| 19 | 21 | #include <linux/bcd.h> |
| 20 | 22 | #include <linux/delay.h> |
| 21 | 23 | #include <linux/io.h> |
| @@ -799,7 +801,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq) · 777 unmodified lines | ||
| 799 | 801 | struct platform_device *pdev = to_platform_device(dev); |
| 800 | 802 | struct ds1685_priv *rtc = platform_get_drvdata(pdev); |
| 801 | 803 | u8 ctrla, ctrlb, ctrlc, ctrld, ctrl4a, ctrl4b, ssn[8]; |
| 802 | − char *model = '\0'; | |
| 804 | + char *model; | |
| 803 | 805 | #ifdef CONFIG_RTC_DS1685_PROC_REGS |
| 804 | 806 | char bits[NUM_REGS][(NUM_BITS * NUM_SPACES) + NUM_BITS + 1]; |
| 805 | 807 | #endif |
| @@ -2139,7 +2141,6 @@ ds1685_rtc_remove(struct platform_device *pdev) · 1333 unmodified lines | ||
| 2139 | 2141 | static struct platform_driver ds1685_rtc_driver = { |
| 2140 | 2142 | .driver = { |
| 2141 | 2143 | .name = "rtc-ds1685", |
| 2142 | − .owner = THIS_MODULE, | |
| 2143 | 2144 | }, |
| 2144 | 2145 | .probe = ds1685_rtc_probe, |
| 2145 | 2146 | .remove = ds1685_rtc_remove, |
| @@ -2175,7 +2176,7 @@ module_exit(ds1685_rtc_exit); · 29 unmodified lines | ||
| 2175 | 2176 | * ds1685_rtc_poweroff - uses the RTC chip to power the system off. |
| 2176 | 2177 | * @pdev: pointer to platform_device structure. |
| 2177 | 2178 | */ |
| 2178 | −extern void __noreturn | |
| 2179 | +void __noreturn | |
| 2179 | 2180 | ds1685_rtc_poweroff(struct platform_device *pdev) |
| 2180 | 2181 | { |
| 2181 | 2182 | u8 ctrla, ctrl4a, ctrl4b; |
| @@ -2183,7 +2184,7 @@ ds1685_rtc_poweroff(struct platform_device *pdev) · 1 unmodified line | ||
| 2183 | 2184 | |
| 2184 | 2185 | /* Check for valid RTC data, else, spin forever. */ |
| 2185 | 2186 | if (unlikely(!pdev)) { |
| 2186 | − pr_emerg("rtc-ds1685: platform device data not available, spinning forever ...\n"); | |
| 2187 | + pr_emerg("platform device data not available, spinning forever ...\n"); | |
| 2187 | 2188 | unreachable(); |
| 2188 | 2189 | } else { |
| 2189 | 2190 | /* Get the rtc data. */ |
| @@ -15,6 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | * "Sending and receiving", using SMBus level communication is preferred. |
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 19 | + | |
| 18 | 20 | #include <linux/kernel.h> |
| 19 | 21 | #include <linux/module.h> |
| 20 | 22 | #include <linux/interrupt.h> |
| @@ -373,8 +375,8 @@ static void ds3232_work(struct work_struct *work) · 352 unmodified lines | ||
| 373 | 375 | if (stat & DS3232_REG_SR_A1F) { |
| 374 | 376 | control = i2c_smbus_read_byte_data(client, DS3232_REG_CR); |
| 375 | 377 | if (control < 0) { |
| 376 | − pr_warn("Read DS3232 Control Register error." | |
| 377 | − "Disable IRQ%d.\n", client->irq); | |
| 378 | + pr_warn("Read Control Register error - Disable IRQ%d\n", | |
| 379 | + client->irq); | |
| 378 | 380 | } else { |
| 379 | 381 | /* disable alarm1 interrupt */ |
| 380 | 382 | control &= ~(DS3232_REG_CR_A1IE); |
| @@ -8,6 +8,9 @@ · 7 unmodified lines | ||
| 8 | 8 | * Copyright (C) 1999-2000 VA Linux Systems |
| 9 | 9 | * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com> |
| 10 | 10 | */ |
| 11 | + | |
| 12 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 13 | + | |
| 11 | 14 | #include <linux/init.h> |
| 12 | 15 | #include <linux/kernel.h> |
| 13 | 16 | #include <linux/module.h> |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/rtc.h> |
| 16 | 16 | #include <linux/bcd.h> |
| 17 | 17 | #include <linux/module.h> |
| 18 | +#include <linux/of.h> | |
| 18 | 19 | |
| 19 | 20 | /* Registers */ |
| 20 | 21 | #define EM3027_REG_ON_OFF_CTRL 0x00 |
| @@ -135,10 +136,20 @@ static struct i2c_device_id em3027_id[] = { · 114 unmodified lines | ||
| 135 | 136 | { "em3027", 0 }, |
| 136 | 137 | { } |
| 137 | 138 | }; |
| 139 | +MODULE_DEVICE_TABLE(i2c, em3027_id); | |
| 140 | + | |
| 141 | +#ifdef CONFIG_OF | |
| 142 | +static const struct of_device_id em3027_of_match[] = { | |
| 143 | + { .compatible = "emmicro,em3027", }, | |
| 144 | + {} | |
| 145 | +}; | |
| 146 | +MODULE_DEVICE_TABLE(of, em3027_of_match); | |
| 147 | +#endif | |
| 138 | 148 | |
| 139 | 149 | static struct i2c_driver em3027_driver = { |
| 140 | 150 | .driver = { |
| 141 | 151 | .name = "rtc-em3027", |
| 152 | + .of_match_table = of_match_ptr(em3027_of_match), | |
| 142 | 153 | }, |
| 143 | 154 | .probe = &em3027_probe, |
| 144 | 155 | .id_table = em3027_id, |
| @@ -66,7 +66,7 @@ · 65 unmodified lines | ||
| 66 | 66 | #define HYM8563_ALM_BIT_DISABLE BIT(7) |
| 67 | 67 | |
| 68 | 68 | #define HYM8563_CLKOUT 0x0d |
| 69 | −#define HYM8563_CLKOUT_DISABLE BIT(7) | |
| 69 | +#define HYM8563_CLKOUT_ENABLE BIT(7) | |
| 70 | 70 | #define HYM8563_CLKOUT_32768 0 |
| 71 | 71 | #define HYM8563_CLKOUT_1024 1 |
| 72 | 72 | #define HYM8563_CLKOUT_32 2 |
| @@ -309,7 +309,7 @@ static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw, · 236 unmodified lines | ||
| 309 | 309 | struct i2c_client *client = hym8563->client; |
| 310 | 310 | int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT); |
| 311 | 311 | |
| 312 | − if (ret < 0 || ret & HYM8563_CLKOUT_DISABLE) | |
| 312 | + if (ret < 0) | |
| 313 | 313 | return 0; |
| 314 | 314 | |
| 315 | 315 | ret &= HYM8563_CLKOUT_MASK; |
| @@ -360,9 +360,9 @@ static int hym8563_clkout_control(struct clk_hw *hw, bool enable) · 44 unmodified lines | ||
| 360 | 360 | return ret; |
| 361 | 361 | |
| 362 | 362 | if (enable) |
| 363 | − ret &= ~HYM8563_CLKOUT_DISABLE; | |
| 363 | + ret |= HYM8563_CLKOUT_ENABLE; | |
| 364 | 364 | else |
| 365 | − ret |= HYM8563_CLKOUT_DISABLE; | |
| 365 | + ret &= ~HYM8563_CLKOUT_ENABLE; | |
| 366 | 366 | |
| 367 | 367 | return i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, ret); |
| 368 | 368 | } |
| @@ -386,7 +386,7 @@ static int hym8563_clkout_is_prepared(struct clk_hw *hw) · 17 unmodified lines | ||
| 386 | 386 | if (ret < 0) |
| 387 | 387 | return ret; |
| 388 | 388 | |
| 389 | − return !(ret & HYM8563_CLKOUT_DISABLE); | |
| 389 | + return !!(ret & HYM8563_CLKOUT_ENABLE); | |
| 390 | 390 | } |
| 391 | 391 | |
| 392 | 392 | static const struct clk_ops hym8563_clkout_ops = { |
| @@ -407,7 +407,7 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563) · 14 unmodified lines | ||
| 407 | 407 | int ret; |
| 408 | 408 | |
| 409 | 409 | ret = i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, |
| 410 | − HYM8563_CLKOUT_DISABLE); | |
| 410 | + 0); | |
| 411 | 411 | if (ret < 0) |
| 412 | 412 | return ERR_PTR(ret); |
| 413 | 413 | |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | * |
| 14 | 14 | */ |
| 15 | 15 | |
| 16 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 17 | + | |
| 16 | 18 | #include <linux/bcd.h> |
| 17 | 19 | #include <linux/i2c.h> |
| 18 | 20 | #include <linux/init.h> |
| @@ -513,12 +515,12 @@ static int wdt_ioctl(struct file *file, unsigned int cmd, · 494 unmodified lines | ||
| 513 | 515 | return -EFAULT; |
| 514 | 516 | |
| 515 | 517 | if (rv & WDIOS_DISABLECARD) { |
| 516 | − pr_info("rtc-m41t80: disable watchdog\n"); | |
| 518 | + pr_info("disable watchdog\n"); | |
| 517 | 519 | wdt_disable(); |
| 518 | 520 | } |
| 519 | 521 | |
| 520 | 522 | if (rv & WDIOS_ENABLECARD) { |
| 521 | − pr_info("rtc-m41t80: enable watchdog\n"); | |
| 523 | + pr_info("enable watchdog\n"); | |
| 522 | 524 | wdt_ping(); |
| 523 | 525 | } |
| 524 | 526 | |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | * |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 16 | + | |
| 15 | 17 | #include <linux/slab.h> |
| 16 | 18 | #include <linux/rtc.h> |
| 17 | 19 | #include <linux/delay.h> |
| @@ -103,8 +105,8 @@ static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data) · 85 unmodified lines | ||
| 103 | 105 | data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; |
| 104 | 106 | |
| 105 | 107 | if (tm->tm_year < 100) { |
| 106 | − pr_warn("%s: MAX77686 RTC cannot handle the year %d." | |
| 107 | − "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); | |
| 108 | + pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n", | |
| 109 | + 1900 + tm->tm_year); | |
| 108 | 110 | return -EINVAL; |
| 109 | 111 | } |
| 110 | 112 | return 0; |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | * |
| 13 | 13 | */ |
| 14 | 14 | |
| 15 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 16 | + | |
| 15 | 17 | #include <linux/slab.h> |
| 16 | 18 | #include <linux/rtc.h> |
| 17 | 19 | #include <linux/delay.h> |
| @@ -107,8 +109,8 @@ static int max8997_rtc_tm_to_data(struct rtc_time *tm, u8 *data) · 89 unmodified lines | ||
| 107 | 109 | data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; |
| 108 | 110 | |
| 109 | 111 | if (tm->tm_year < 100) { |
| 110 | − pr_warn("%s: MAX8997 RTC cannot handle the year %d." | |
| 111 | − "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); | |
| 112 | + pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n", | |
| 113 | + 1900 + tm->tm_year); | |
| 112 | 114 | return -EINVAL; |
| 113 | 115 | } |
| 114 | 116 | return 0; |
| @@ -424,7 +426,7 @@ static void max8997_rtc_enable_smpl(struct max8997_rtc_info *info, bool enable) · 309 unmodified lines | ||
| 424 | 426 | |
| 425 | 427 | val = 0; |
| 426 | 428 | max8997_read_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, &val); |
| 427 | − pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val); | |
| 429 | + pr_info("WTSR_SMPL(0x%02x)\n", val); | |
| 428 | 430 | } |
| 429 | 431 | |
| 430 | 432 | static int max8997_rtc_init_reg(struct max8997_rtc_info *info) |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | * Copyright (C) 1993 Hamish Macdonald |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 11 | + | |
| 10 | 12 | #include <linux/delay.h> |
| 11 | 13 | #include <linux/io.h> |
| 12 | 14 | #include <linux/kernel.h> |
| @@ -111,7 +113,7 @@ static void msm6242_lock(struct msm6242_priv *priv) · 98 unmodified lines | ||
| 111 | 113 | } |
| 112 | 114 | |
| 113 | 115 | if (!cnt) |
| 114 | − pr_warn("msm6242: timed out waiting for RTC (0x%x)\n", | |
| 116 | + pr_warn("timed out waiting for RTC (0x%x)\n", | |
| 115 | 117 | msm6242_read(priv, MSM6242_CD)); |
| 116 | 118 | } |
| 117 | 119 | |
| @@ -118,12 +118,15 @@ · 117 unmodified lines | ||
| 118 | 118 | #define KICK0_VALUE 0x83e70b13 |
| 119 | 119 | #define KICK1_VALUE 0x95a4f1e0 |
| 120 | 120 | |
| 121 | +struct omap_rtc; | |
| 122 | + | |
| 121 | 123 | struct omap_rtc_device_type { |
| 122 | 124 | bool has_32kclk_en; |
| 123 | − bool has_kicker; | |
| 124 | 125 | bool has_irqwakeen; |
| 125 | 126 | bool has_pmic_mode; |
| 126 | 127 | bool has_power_up_reset; |
| 128 | + void (*lock)(struct omap_rtc *rtc); | |
| 129 | + void (*unlock)(struct omap_rtc *rtc); | |
| 127 | 130 | }; |
| 128 | 131 | |
| 129 | 132 | struct omap_rtc { |
| @@ -156,6 +159,26 @@ static inline void rtc_writel(struct omap_rtc *rtc, unsigned int reg, u32 val) · 26 unmodified lines | ||
| 156 | 159 | writel(val, rtc->base + reg); |
| 157 | 160 | } |
| 158 | 161 | |
| 162 | +static void am3352_rtc_unlock(struct omap_rtc *rtc) | |
| 163 | +{ | |
| 164 | + rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); | |
| 165 | + rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); | |
| 166 | +} | |
| 167 | + | |
| 168 | +static void am3352_rtc_lock(struct omap_rtc *rtc) | |
| 169 | +{ | |
| 170 | + rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); | |
| 171 | + rtc_writel(rtc, OMAP_RTC_KICK1_REG, 0); | |
| 172 | +} | |
| 173 | + | |
| 174 | +static void default_rtc_unlock(struct omap_rtc *rtc) | |
| 175 | +{ | |
| 176 | +} | |
| 177 | + | |
| 178 | +static void default_rtc_lock(struct omap_rtc *rtc) | |
| 179 | +{ | |
| 180 | +} | |
| 181 | + | |
| 159 | 182 | /* |
| 160 | 183 | * We rely on the rtc framework to handle locking (rtc->ops_lock), |
| 161 | 184 | * so the only other requirement is that register accesses which |
| @@ -186,7 +209,9 @@ static irqreturn_t rtc_irq(int irq, void *dev_id) · 24 unmodified lines | ||
| 186 | 209 | |
| 187 | 210 | /* alarm irq? */ |
| 188 | 211 | if (irq_data & OMAP_RTC_STATUS_ALARM) { |
| 212 | + rtc->type->unlock(rtc); | |
| 189 | 213 | rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM); |
| 214 | + rtc->type->lock(rtc); | |
| 190 | 215 | events |= RTC_IRQF | RTC_AF; |
| 191 | 216 | } |
| 192 | 217 | |
| @@ -218,9 +243,11 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) · 25 unmodified lines | ||
| 218 | 243 | irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; |
| 219 | 244 | } |
| 220 | 245 | rtc_wait_not_busy(rtc); |
| 246 | + rtc->type->unlock(rtc); | |
| 221 | 247 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); |
| 222 | 248 | if (rtc->type->has_irqwakeen) |
| 223 | 249 | rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); |
| 250 | + rtc->type->lock(rtc); | |
| 224 | 251 | local_irq_enable(); |
| 225 | 252 | |
| 226 | 253 | return 0; |
| @@ -293,12 +320,14 @@ static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm) · 66 unmodified lines | ||
| 293 | 320 | local_irq_disable(); |
| 294 | 321 | rtc_wait_not_busy(rtc); |
| 295 | 322 | |
| 323 | + rtc->type->unlock(rtc); | |
| 296 | 324 | rtc_write(rtc, OMAP_RTC_YEARS_REG, tm->tm_year); |
| 297 | 325 | rtc_write(rtc, OMAP_RTC_MONTHS_REG, tm->tm_mon); |
| 298 | 326 | rtc_write(rtc, OMAP_RTC_DAYS_REG, tm->tm_mday); |
| 299 | 327 | rtc_write(rtc, OMAP_RTC_HOURS_REG, tm->tm_hour); |
| 300 | 328 | rtc_write(rtc, OMAP_RTC_MINUTES_REG, tm->tm_min); |
| 301 | 329 | rtc_write(rtc, OMAP_RTC_SECONDS_REG, tm->tm_sec); |
| 330 | + rtc->type->lock(rtc); | |
| 302 | 331 | |
| 303 | 332 | local_irq_enable(); |
| 304 | 333 | |
| @@ -341,6 +370,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) · 36 unmodified lines | ||
| 341 | 370 | local_irq_disable(); |
| 342 | 371 | rtc_wait_not_busy(rtc); |
| 343 | 372 | |
| 373 | + rtc->type->unlock(rtc); | |
| 344 | 374 | rtc_write(rtc, OMAP_RTC_ALARM_YEARS_REG, alm->time.tm_year); |
| 345 | 375 | rtc_write(rtc, OMAP_RTC_ALARM_MONTHS_REG, alm->time.tm_mon); |
| 346 | 376 | 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) · 15 unmodified lines | ||
| 362 | 392 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); |
| 363 | 393 | if (rtc->type->has_irqwakeen) |
| 364 | 394 | rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); |
| 395 | + rtc->type->lock(rtc); | |
| 365 | 396 | |
| 366 | 397 | local_irq_enable(); |
| 367 | 398 | |
| @@ -391,6 +422,7 @@ static void omap_rtc_power_off(void) · 23 unmodified lines | ||
| 391 | 422 | unsigned long now; |
| 392 | 423 | u32 val; |
| 393 | 424 | |
| 425 | + rtc->type->unlock(rtc); | |
| 394 | 426 | /* enable pmic_power_en control */ |
| 395 | 427 | val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); |
| 396 | 428 | 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) · 26 unmodified lines | ||
| 423 | 455 | val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); |
| 424 | 456 | rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, |
| 425 | 457 | val | OMAP_RTC_INTERRUPTS_IT_ALARM2); |
| 458 | + rtc->type->lock(rtc); | |
| 426 | 459 | |
| 427 | 460 | /* |
| 428 | 461 | * Wait for alarm to trigger (within two seconds) and external PMIC to |
| @@ -442,17 +475,21 @@ static struct rtc_class_ops omap_rtc_ops = { · 13 unmodified lines | ||
| 442 | 475 | |
| 443 | 476 | static const struct omap_rtc_device_type omap_rtc_default_type = { |
| 444 | 477 | .has_power_up_reset = true, |
| 478 | + .lock = default_rtc_lock, | |
| 479 | + .unlock = default_rtc_unlock, | |
| 445 | 480 | }; |
| 446 | 481 | |
| 447 | 482 | static const struct omap_rtc_device_type omap_rtc_am3352_type = { |
| 448 | 483 | .has_32kclk_en = true, |
| 449 | − .has_kicker = true, | |
| 450 | 484 | .has_irqwakeen = true, |
| 451 | 485 | .has_pmic_mode = true, |
| 486 | + .lock = am3352_rtc_lock, | |
| 487 | + .unlock = am3352_rtc_unlock, | |
| 452 | 488 | }; |
| 453 | 489 | |
| 454 | 490 | static const struct omap_rtc_device_type omap_rtc_da830_type = { |
| 455 | − .has_kicker = true, | |
| 491 | + .lock = am3352_rtc_lock, | |
| 492 | + .unlock = am3352_rtc_unlock, | |
| 456 | 493 | }; |
| 457 | 494 | |
| 458 | 495 | static const struct platform_device_id omap_rtc_id_table[] = { |
| @@ -484,7 +521,7 @@ static const struct of_device_id omap_rtc_of_match[] = { · 25 unmodified lines | ||
| 484 | 521 | }; |
| 485 | 522 | MODULE_DEVICE_TABLE(of, omap_rtc_of_match); |
| 486 | 523 | |
| 487 | −static int __init omap_rtc_probe(struct platform_device *pdev) | |
| 524 | +static int omap_rtc_probe(struct platform_device *pdev) | |
| 488 | 525 | { |
| 489 | 526 | struct omap_rtc *rtc; |
| 490 | 527 | struct resource *res; |
| @@ -527,10 +564,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) · 36 unmodified lines | ||
| 527 | 564 | pm_runtime_enable(&pdev->dev); |
| 528 | 565 | pm_runtime_get_sync(&pdev->dev); |
| 529 | 566 | |
| 530 | − if (rtc->type->has_kicker) { | |
| 531 | − rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); | |
| 532 | − rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); | |
| 533 | − } | |
| 567 | + rtc->type->unlock(rtc); | |
| 534 | 568 | |
| 535 | 569 | /* |
| 536 | 570 | * disable interrupts |
| @@ -593,6 +627,8 @@ static int __init omap_rtc_probe(struct platform_device *pdev) · 56 unmodified lines | ||
| 593 | 627 | if (reg != new_ctrl) |
| 594 | 628 | rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); |
| 595 | 629 | |
| 630 | + rtc->type->lock(rtc); | |
| 631 | + | |
| 596 | 632 | device_init_wakeup(&pdev->dev, true); |
| 597 | 633 | |
| 598 | 634 | rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, |
| @@ -626,8 +662,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) · 27 unmodified lines | ||
| 626 | 662 | |
| 627 | 663 | err: |
| 628 | 664 | device_init_wakeup(&pdev->dev, false); |
| 629 | − if (rtc->type->has_kicker) | |
| 630 | − rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); | |
| 665 | + rtc->type->lock(rtc); | |
| 631 | 666 | pm_runtime_put_sync(&pdev->dev); |
| 632 | 667 | pm_runtime_disable(&pdev->dev); |
| 633 | 668 | |
| @@ -646,11 +681,11 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) · 12 unmodified lines | ||
| 646 | 681 | |
| 647 | 682 | device_init_wakeup(&pdev->dev, 0); |
| 648 | 683 | |
| 684 | + rtc->type->unlock(rtc); | |
| 649 | 685 | /* leave rtc running, but disable irqs */ |
| 650 | 686 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); |
| 651 | 687 | |
| 652 | − if (rtc->type->has_kicker) | |
| 653 | − rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); | |
| 688 | + rtc->type->lock(rtc); | |
| 654 | 689 | |
| 655 | 690 | /* Disable the clock/module */ |
| 656 | 691 | pm_runtime_put_sync(&pdev->dev); |
| @@ -666,6 +701,7 @@ static int omap_rtc_suspend(struct device *dev) · 9 unmodified lines | ||
| 666 | 701 | |
| 667 | 702 | rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); |
| 668 | 703 | |
| 704 | + rtc->type->unlock(rtc); | |
| 669 | 705 | /* |
| 670 | 706 | * FIXME: the RTC alarm is not currently acting as a wakeup event |
| 671 | 707 | * source on some platforms, and in fact this enable() call is just |
| @@ -675,6 +711,7 @@ static int omap_rtc_suspend(struct device *dev) · 3 unmodified lines | ||
| 675 | 711 | enable_irq_wake(rtc->irq_alarm); |
| 676 | 712 | else |
| 677 | 713 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); |
| 714 | + rtc->type->lock(rtc); | |
| 678 | 715 | |
| 679 | 716 | /* Disable the clock/module */ |
| 680 | 717 | pm_runtime_put_sync(dev); |
| @@ -689,10 +726,12 @@ static int omap_rtc_resume(struct device *dev) · 8 unmodified lines | ||
| 689 | 726 | /* Enable the clock/module so that we can access the registers */ |
| 690 | 727 | pm_runtime_get_sync(dev); |
| 691 | 728 | |
| 729 | + rtc->type->unlock(rtc); | |
| 692 | 730 | if (device_may_wakeup(dev)) |
| 693 | 731 | disable_irq_wake(rtc->irq_alarm); |
| 694 | 732 | else |
| 695 | 733 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg); |
| 734 | + rtc->type->lock(rtc); | |
| 696 | 735 | |
| 697 | 736 | return 0; |
| 698 | 737 | } |
| @@ -709,12 +748,15 @@ static void omap_rtc_shutdown(struct platform_device *pdev) · 10 unmodified lines | ||
| 709 | 748 | * Keep the ALARM interrupt enabled to allow the system to power up on |
| 710 | 749 | * alarm events. |
| 711 | 750 | */ |
| 751 | + rtc->type->unlock(rtc); | |
| 712 | 752 | mask = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); |
| 713 | 753 | mask &= OMAP_RTC_INTERRUPTS_IT_ALARM; |
| 714 | 754 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, mask); |
| 755 | + rtc->type->lock(rtc); | |
| 715 | 756 | } |
| 716 | 757 | |
| 717 | 758 | static struct platform_driver omap_rtc_driver = { |
| 759 | + .probe = omap_rtc_probe, | |
| 718 | 760 | .remove = __exit_p(omap_rtc_remove), |
| 719 | 761 | .shutdown = omap_rtc_shutdown, |
| 720 | 762 | .driver = { |
| @@ -725,7 +767,7 @@ static struct platform_driver omap_rtc_driver = { · 4 unmodified lines | ||
| 725 | 767 | .id_table = omap_rtc_id_table, |
| 726 | 768 | }; |
| 727 | 769 | |
| 728 | −module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe); | |
| 770 | +module_platform_driver(omap_rtc_driver); | |
| 729 | 771 | |
| 730 | 772 | MODULE_ALIAS("platform:omap_rtc"); |
| 731 | 773 | MODULE_AUTHOR("George G. Davis (and others)"); |
| @@ -16,8 +16,9 @@ · 15 unmodified lines | ||
| 16 | 16 | * along with this program. |
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 20 | + | |
| 19 | 21 | #define DRVNAME "rtc-opal" |
| 20 | −#define pr_fmt(fmt) DRVNAME ": " fmt | |
| 21 | 22 | |
| 22 | 23 | #include <linux/module.h> |
| 23 | 24 | #include <linux/err.h> |
| @@ -246,7 +246,6 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) · 245 unmodified lines | ||
| 246 | 246 | static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
| 247 | 247 | { |
| 248 | 248 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); |
| 249 | − int err; | |
| 250 | 249 | unsigned char buf[9]; |
| 251 | 250 | |
| 252 | 251 | 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) · 19 unmodified lines | ||
| 272 | 271 | |
| 273 | 272 | buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; |
| 274 | 273 | |
| 275 | − err = pcf8563_write_block_data(client, PCF8563_REG_SC, | |
| 274 | + return pcf8563_write_block_data(client, PCF8563_REG_SC, | |
| 276 | 275 | 9 - PCF8563_REG_SC, buf + PCF8563_REG_SC); |
| 277 | − if (err) | |
| 278 | − return err; | |
| 279 | − | |
| 280 | − return 0; | |
| 281 | 276 | } |
| 282 | 277 | |
| 283 | 278 | #ifdef CONFIG_RTC_INTF_DEV |
| @@ -39,7 +39,6 @@ struct s3c_rtc { · 38 unmodified lines | ||
| 39 | 39 | void __iomem *base; |
| 40 | 40 | struct clk *rtc_clk; |
| 41 | 41 | struct clk *rtc_src_clk; |
| 42 | − bool enabled; | |
| 43 | 42 | |
| 44 | 43 | struct s3c_rtc_data *data; |
| 45 | 44 | |
| @@ -67,26 +66,25 @@ struct s3c_rtc_data { · 21 unmodified lines | ||
| 67 | 66 | void (*disable) (struct s3c_rtc *info); |
| 68 | 67 | }; |
| 69 | 68 | |
| 70 | −static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable) | |
| 69 | +static void s3c_rtc_enable_clk(struct s3c_rtc *info) | |
| 71 | 70 | { |
| 72 | 71 | unsigned long irq_flags; |
| 73 | 72 | |
| 74 | 73 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); |
| 75 | − if (enable) { | |
| 76 | − if (!info->enabled) { | |
| 77 | − clk_enable(info->rtc_clk); | |
| 78 | − if (info->data->needs_src_clk) | |
| 79 | − clk_enable(info->rtc_src_clk); | |
| 80 | − info->enabled = true; | |
| 81 | − } | |
| 82 | − } else { | |
| 83 | − if (info->enabled) { | |
| 84 | − if (info->data->needs_src_clk) | |
| 85 | − clk_disable(info->rtc_src_clk); | |
| 86 | − clk_disable(info->rtc_clk); | |
| 87 | − info->enabled = false; | |
| 88 | − } | |
| 89 | − } | |
| 74 | + clk_enable(info->rtc_clk); | |
| 75 | + if (info->data->needs_src_clk) | |
| 76 | + clk_enable(info->rtc_src_clk); | |
| 77 | + spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); | |
| 78 | +} | |
| 79 | + | |
| 80 | +static void s3c_rtc_disable_clk(struct s3c_rtc *info) | |
| 81 | +{ | |
| 82 | + unsigned long irq_flags; | |
| 83 | + | |
| 84 | + spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); | |
| 85 | + if (info->data->needs_src_clk) | |
| 86 | + clk_disable(info->rtc_src_clk); | |
| 87 | + clk_disable(info->rtc_clk); | |
| 90 | 88 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); |
| 91 | 89 | } |
| 92 | 90 | |
| @@ -119,20 +117,16 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) · 26 unmodified lines | ||
| 119 | 117 | |
| 120 | 118 | dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled); |
| 121 | 119 | |
| 122 | − clk_enable(info->rtc_clk); | |
| 123 | − if (info->data->needs_src_clk) | |
| 124 | − clk_enable(info->rtc_src_clk); | |
| 120 | + s3c_rtc_enable_clk(info); | |
| 121 | + | |
| 125 | 122 | tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; |
| 126 | 123 | |
| 127 | 124 | if (enabled) |
| 128 | 125 | tmp |= S3C2410_RTCALM_ALMEN; |
| 129 | 126 | |
| 130 | 127 | writeb(tmp, info->base + S3C2410_RTCALM); |
| 131 | − if (info->data->needs_src_clk) | |
| 132 | − clk_disable(info->rtc_src_clk); | |
| 133 | − clk_disable(info->rtc_clk); | |
| 134 | 128 | |
| 135 | − s3c_rtc_alarm_clk_enable(info, enabled); | |
| 129 | + s3c_rtc_disable_clk(info); | |
| 136 | 130 | |
| 137 | 131 | return 0; |
| 138 | 132 | } |
| @@ -143,18 +137,12 @@ static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) · 4 unmodified lines | ||
| 143 | 137 | if (!is_power_of_2(freq)) |
| 144 | 138 | return -EINVAL; |
| 145 | 139 | |
| 146 | − clk_enable(info->rtc_clk); | |
| 147 | − if (info->data->needs_src_clk) | |
| 148 | − clk_enable(info->rtc_src_clk); | |
| 149 | 140 | spin_lock_irq(&info->pie_lock); |
| 150 | 141 | |
| 151 | 142 | if (info->data->set_freq) |
| 152 | 143 | info->data->set_freq(info, freq); |
| 153 | 144 | |
| 154 | 145 | spin_unlock_irq(&info->pie_lock); |
| 155 | − if (info->data->needs_src_clk) | |
| 156 | − clk_disable(info->rtc_src_clk); | |
| 157 | − clk_disable(info->rtc_clk); | |
| 158 | 146 | |
| 159 | 147 | return 0; |
| 160 | 148 | } |
| @@ -165,9 +153,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) · 4 unmodified lines | ||
| 165 | 153 | struct s3c_rtc *info = dev_get_drvdata(dev); |
| 166 | 154 | unsigned int have_retried = 0; |
| 167 | 155 | |
| 168 | − clk_enable(info->rtc_clk); | |
| 169 | − if (info->data->needs_src_clk) | |
| 170 | − clk_enable(info->rtc_src_clk); | |
| 156 | + s3c_rtc_enable_clk(info); | |
| 171 | 157 | |
| 172 | 158 | retry_get_time: |
| 173 | 159 | 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) · 20 unmodified lines | ||
| 194 | 180 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
| 195 | 181 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
| 196 | 182 | |
| 183 | + s3c_rtc_disable_clk(info); | |
| 184 | + | |
| 197 | 185 | rtc_tm->tm_year += 100; |
| 198 | 186 | |
| 199 | 187 | 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) · 2 unmodified lines | ||
| 202 | 190 | |
| 203 | 191 | rtc_tm->tm_mon -= 1; |
| 204 | 192 | |
| 205 | − if (info->data->needs_src_clk) | |
| 206 | − clk_disable(info->rtc_src_clk); | |
| 207 | − clk_disable(info->rtc_clk); | |
| 208 | − | |
| 209 | 193 | return rtc_valid_tm(rtc_tm); |
| 210 | 194 | } |
| 211 | 195 | |
| @@ -225,9 +209,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) · 13 unmodified lines | ||
| 225 | 209 | return -EINVAL; |
| 226 | 210 | } |
| 227 | 211 | |
| 228 | − clk_enable(info->rtc_clk); | |
| 229 | − if (info->data->needs_src_clk) | |
| 230 | − clk_enable(info->rtc_src_clk); | |
| 212 | + s3c_rtc_enable_clk(info); | |
| 231 | 213 | |
| 232 | 214 | writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC); |
| 233 | 215 | 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) · 2 unmodified lines | ||
| 236 | 218 | writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON); |
| 237 | 219 | writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR); |
| 238 | 220 | |
| 239 | − if (info->data->needs_src_clk) | |
| 240 | − clk_disable(info->rtc_src_clk); | |
| 241 | − clk_disable(info->rtc_clk); | |
| 221 | + s3c_rtc_disable_clk(info); | |
| 242 | 222 | |
| 243 | 223 | return 0; |
| 244 | 224 | } |
| @@ -249,9 +229,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) · 4 unmodified lines | ||
| 249 | 229 | struct rtc_time *alm_tm = &alrm->time; |
| 250 | 230 | unsigned int alm_en; |
| 251 | 231 | |
| 252 | − clk_enable(info->rtc_clk); | |
| 253 | − if (info->data->needs_src_clk) | |
| 254 | − clk_enable(info->rtc_src_clk); | |
| 232 | + s3c_rtc_enable_clk(info); | |
| 255 | 233 | |
| 256 | 234 | alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC); |
| 257 | 235 | 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) · 4 unmodified lines | ||
| 262 | 240 | |
| 263 | 241 | alm_en = readb(info->base + S3C2410_RTCALM); |
| 264 | 242 | |
| 243 | + s3c_rtc_disable_clk(info); | |
| 244 | + | |
| 265 | 245 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; |
| 266 | 246 | |
| 267 | 247 | 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) · 1 unmodified line | ||
| 269 | 249 | 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, |
| 270 | 250 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); |
| 271 | 251 | |
| 272 | − | |
| 273 | 252 | /* decode the alarm enable field */ |
| 274 | − | |
| 275 | 253 | if (alm_en & S3C2410_RTCALM_SECEN) |
| 276 | 254 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); |
| 277 | 255 | else |
| @@ -304,10 +282,6 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) · 26 unmodified lines | ||
| 304 | 282 | else |
| 305 | 283 | alm_tm->tm_year = -1; |
| 306 | 284 | |
| 307 | − if (info->data->needs_src_clk) | |
| 308 | − clk_disable(info->rtc_src_clk); | |
| 309 | − clk_disable(info->rtc_clk); | |
| 310 | − | |
| 311 | 285 | return 0; |
| 312 | 286 | } |
| 313 | 287 | |
| @@ -317,15 +291,13 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) · 3 unmodified lines | ||
| 317 | 291 | struct rtc_time *tm = &alrm->time; |
| 318 | 292 | unsigned int alrm_en; |
| 319 | 293 | |
| 320 | − clk_enable(info->rtc_clk); | |
| 321 | − if (info->data->needs_src_clk) | |
| 322 | − clk_enable(info->rtc_src_clk); | |
| 323 | − | |
| 324 | 294 | dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
| 325 | 295 | alrm->enabled, |
| 326 | 296 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, |
| 327 | 297 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
| 328 | 298 | |
| 299 | + s3c_rtc_enable_clk(info); | |
| 300 | + | |
| 329 | 301 | alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; |
| 330 | 302 | writeb(0x00, info->base + S3C2410_RTCALM); |
| 331 | 303 | |
| @@ -348,11 +320,9 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) · 16 unmodified lines | ||
| 348 | 320 | |
| 349 | 321 | writeb(alrm_en, info->base + S3C2410_RTCALM); |
| 350 | 322 | |
| 351 | − s3c_rtc_setaie(dev, alrm->enabled); | |
| 323 | + s3c_rtc_disable_clk(info); | |
| 352 | 324 | |
| 353 | − if (info->data->needs_src_clk) | |
| 354 | − clk_disable(info->rtc_src_clk); | |
| 355 | − clk_disable(info->rtc_clk); | |
| 325 | + s3c_rtc_setaie(dev, alrm->enabled); | |
| 356 | 326 | |
| 357 | 327 | return 0; |
| 358 | 328 | } |
| @@ -361,16 +331,12 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) · 2 unmodified lines | ||
| 361 | 331 | { |
| 362 | 332 | struct s3c_rtc *info = dev_get_drvdata(dev); |
| 363 | 333 | |
| 364 | − clk_enable(info->rtc_clk); | |
| 365 | − if (info->data->needs_src_clk) | |
| 366 | − clk_enable(info->rtc_src_clk); | |
| 334 | + s3c_rtc_enable_clk(info); | |
| 367 | 335 | |
| 368 | 336 | if (info->data->enable_tick) |
| 369 | 337 | info->data->enable_tick(info, seq); |
| 370 | 338 | |
| 371 | − if (info->data->needs_src_clk) | |
| 372 | − clk_disable(info->rtc_src_clk); | |
| 373 | − clk_disable(info->rtc_clk); | |
| 339 | + s3c_rtc_disable_clk(info); | |
| 374 | 340 | |
| 375 | 341 | return 0; |
| 376 | 342 | } |
| @@ -388,10 +354,6 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info) · 11 unmodified lines | ||
| 388 | 354 | { |
| 389 | 355 | unsigned int con, tmp; |
| 390 | 356 | |
| 391 | − clk_enable(info->rtc_clk); | |
| 392 | − if (info->data->needs_src_clk) | |
| 393 | − clk_enable(info->rtc_src_clk); | |
| 394 | − | |
| 395 | 357 | con = readw(info->base + S3C2410_RTCCON); |
| 396 | 358 | /* re-enable the device, and check it is ok */ |
| 397 | 359 | if ((con & S3C2410_RTCCON_RTCEN) == 0) { |
| @@ -417,20 +379,12 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info) · 19 unmodified lines | ||
| 417 | 379 | writew(tmp & ~S3C2410_RTCCON_CLKRST, |
| 418 | 380 | info->base + S3C2410_RTCCON); |
| 419 | 381 | } |
| 420 | − | |
| 421 | − if (info->data->needs_src_clk) | |
| 422 | − clk_disable(info->rtc_src_clk); | |
| 423 | − clk_disable(info->rtc_clk); | |
| 424 | 382 | } |
| 425 | 383 | |
| 426 | 384 | static void s3c24xx_rtc_disable(struct s3c_rtc *info) |
| 427 | 385 | { |
| 428 | 386 | unsigned int con; |
| 429 | 387 | |
| 430 | − clk_enable(info->rtc_clk); | |
| 431 | − if (info->data->needs_src_clk) | |
| 432 | − clk_enable(info->rtc_src_clk); | |
| 433 | − | |
| 434 | 388 | con = readw(info->base + S3C2410_RTCCON); |
| 435 | 389 | con &= ~S3C2410_RTCCON_RTCEN; |
| 436 | 390 | writew(con, info->base + S3C2410_RTCCON); |
| @@ -438,28 +392,16 @@ static void s3c24xx_rtc_disable(struct s3c_rtc *info) · 1 unmodified line | ||
| 438 | 392 | con = readb(info->base + S3C2410_TICNT); |
| 439 | 393 | con &= ~S3C2410_TICNT_ENABLE; |
| 440 | 394 | writeb(con, info->base + S3C2410_TICNT); |
| 441 | − | |
| 442 | − if (info->data->needs_src_clk) | |
| 443 | − clk_disable(info->rtc_src_clk); | |
| 444 | − clk_disable(info->rtc_clk); | |
| 445 | 395 | } |
| 446 | 396 | |
| 447 | 397 | static void s3c6410_rtc_disable(struct s3c_rtc *info) |
| 448 | 398 | { |
| 449 | 399 | unsigned int con; |
| 450 | 400 | |
| 451 | − clk_enable(info->rtc_clk); | |
| 452 | − if (info->data->needs_src_clk) | |
| 453 | − clk_enable(info->rtc_src_clk); | |
| 454 | − | |
| 455 | 401 | con = readw(info->base + S3C2410_RTCCON); |
| 456 | 402 | con &= ~S3C64XX_RTCCON_TICEN; |
| 457 | 403 | con &= ~S3C2410_RTCCON_RTCEN; |
| 458 | 404 | writew(con, info->base + S3C2410_RTCCON); |
| 459 | − | |
| 460 | − if (info->data->needs_src_clk) | |
| 461 | − clk_disable(info->rtc_src_clk); | |
| 462 | − clk_disable(info->rtc_clk); | |
| 463 | 405 | } |
| 464 | 406 | |
| 465 | 407 | static int s3c_rtc_remove(struct platform_device *pdev) |
| @@ -554,6 +496,20 @@ static int s3c_rtc_probe(struct platform_device *pdev) · 88 unmodified lines | ||
| 554 | 496 | |
| 555 | 497 | device_init_wakeup(&pdev->dev, 1); |
| 556 | 498 | |
| 499 | + /* Check RTC Time */ | |
| 500 | + if (s3c_rtc_gettime(&pdev->dev, &rtc_tm)) { | |
| 501 | + rtc_tm.tm_year = 100; | |
| 502 | + rtc_tm.tm_mon = 0; | |
| 503 | + rtc_tm.tm_mday = 1; | |
| 504 | + rtc_tm.tm_hour = 0; | |
| 505 | + rtc_tm.tm_min = 0; | |
| 506 | + rtc_tm.tm_sec = 0; | |
| 507 | + | |
| 508 | + s3c_rtc_settime(&pdev->dev, &rtc_tm); | |
| 509 | + | |
| 510 | + dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); | |
| 511 | + } | |
| 512 | + | |
| 557 | 513 | /* register RTC and exit */ |
| 558 | 514 | info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, |
| 559 | 515 | THIS_MODULE); |
| @@ -577,36 +533,21 @@ static int s3c_rtc_probe(struct platform_device *pdev) · 17 unmodified lines | ||
| 577 | 533 | goto err_nortc; |
| 578 | 534 | } |
| 579 | 535 | |
| 580 | − /* Check RTC Time */ | |
| 581 | − s3c_rtc_gettime(&pdev->dev, &rtc_tm); | |
| 582 | − | |
| 583 | − if (rtc_valid_tm(&rtc_tm)) { | |
| 584 | − rtc_tm.tm_year = 100; | |
| 585 | − rtc_tm.tm_mon = 0; | |
| 586 | − rtc_tm.tm_mday = 1; | |
| 587 | − rtc_tm.tm_hour = 0; | |
| 588 | − rtc_tm.tm_min = 0; | |
| 589 | − rtc_tm.tm_sec = 0; | |
| 590 | − | |
| 591 | − s3c_rtc_settime(&pdev->dev, &rtc_tm); | |
| 592 | − | |
| 593 | − dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); | |
| 594 | − } | |
| 595 | − | |
| 596 | 536 | if (info->data->select_tick_clk) |
| 597 | 537 | info->data->select_tick_clk(info); |
| 598 | 538 | |
| 599 | 539 | s3c_rtc_setfreq(info, 1); |
| 600 | 540 | |
| 601 | − if (info->data->needs_src_clk) | |
| 602 | − clk_disable(info->rtc_src_clk); | |
| 603 | − clk_disable(info->rtc_clk); | |
| 541 | + s3c_rtc_disable_clk(info); | |
| 604 | 542 | |
| 605 | 543 | return 0; |
| 606 | 544 | |
| 607 | 545 | err_nortc: |
| 608 | 546 | if (info->data->disable) |
| 609 | 547 | info->data->disable(info); |
| 548 | + | |
| 549 | + if (info->data->needs_src_clk) | |
| 550 | + clk_disable_unprepare(info->rtc_src_clk); | |
| 610 | 551 | clk_disable_unprepare(info->rtc_clk); |
| 611 | 552 | |
| 612 | 553 | return ret; |
| @@ -618,9 +559,7 @@ static int s3c_rtc_suspend(struct device *dev) · 5 unmodified lines | ||
| 618 | 559 | { |
| 619 | 560 | struct s3c_rtc *info = dev_get_drvdata(dev); |
| 620 | 561 | |
| 621 | − clk_enable(info->rtc_clk); | |
| 622 | − if (info->data->needs_src_clk) | |
| 623 | − clk_enable(info->rtc_src_clk); | |
| 562 | + s3c_rtc_enable_clk(info); | |
| 624 | 563 | |
| 625 | 564 | /* save TICNT for anyone using periodic interrupts */ |
| 626 | 565 | if (info->data->save_tick_cnt) |
| @@ -636,10 +575,6 @@ static int s3c_rtc_suspend(struct device *dev) · 9 unmodified lines | ||
| 636 | 575 | dev_err(dev, "enable_irq_wake failed\n"); |
| 637 | 576 | } |
| 638 | 577 | |
| 639 | − if (info->data->needs_src_clk) | |
| 640 | − clk_disable(info->rtc_src_clk); | |
| 641 | − clk_disable(info->rtc_clk); | |
| 642 | − | |
| 643 | 578 | return 0; |
| 644 | 579 | } |
| 645 | 580 | |
| @@ -647,25 +582,19 @@ static int s3c_rtc_resume(struct device *dev) · 1 unmodified line | ||
| 647 | 582 | { |
| 648 | 583 | struct s3c_rtc *info = dev_get_drvdata(dev); |
| 649 | 584 | |
| 650 | − clk_enable(info->rtc_clk); | |
| 651 | − if (info->data->needs_src_clk) | |
| 652 | − clk_enable(info->rtc_src_clk); | |
| 653 | − | |
| 654 | 585 | if (info->data->enable) |
| 655 | 586 | info->data->enable(info); |
| 656 | 587 | |
| 657 | 588 | if (info->data->restore_tick_cnt) |
| 658 | 589 | info->data->restore_tick_cnt(info); |
| 659 | 590 | |
| 591 | + s3c_rtc_disable_clk(info); | |
| 592 | + | |
| 660 | 593 | if (device_may_wakeup(dev) && info->wake_en) { |
| 661 | 594 | disable_irq_wake(info->irq_alarm); |
| 662 | 595 | info->wake_en = false; |
| 663 | 596 | } |
| 664 | 597 | |
| 665 | − if (info->data->needs_src_clk) | |
| 666 | − clk_disable(info->rtc_src_clk); | |
| 667 | − clk_disable(info->rtc_clk); | |
| 668 | − | |
| 669 | 598 | return 0; |
| 670 | 599 | } |
| 671 | 600 | #endif |
| @@ -673,29 +602,13 @@ static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); · 1 unmodified line | ||
| 673 | 602 | |
| 674 | 603 | static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) |
| 675 | 604 | { |
| 676 | − clk_enable(info->rtc_clk); | |
| 677 | − if (info->data->needs_src_clk) | |
| 678 | − clk_enable(info->rtc_src_clk); | |
| 679 | 605 | rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); |
| 680 | − if (info->data->needs_src_clk) | |
| 681 | − clk_disable(info->rtc_src_clk); | |
| 682 | − clk_disable(info->rtc_clk); | |
| 683 | − | |
| 684 | − s3c_rtc_alarm_clk_enable(info, false); | |
| 685 | 606 | } |
| 686 | 607 | |
| 687 | 608 | static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) |
| 688 | 609 | { |
| 689 | − clk_enable(info->rtc_clk); | |
| 690 | − if (info->data->needs_src_clk) | |
| 691 | − clk_enable(info->rtc_src_clk); | |
| 692 | 610 | rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); |
| 693 | 611 | writeb(mask, info->base + S3C2410_INTP); |
| 694 | − if (info->data->needs_src_clk) | |
| 695 | − clk_disable(info->rtc_src_clk); | |
| 696 | − clk_disable(info->rtc_clk); | |
| 697 | − | |
| 698 | − s3c_rtc_alarm_clk_enable(info, false); | |
| 699 | 612 | } |
| 700 | 613 | |
| 701 | 614 | static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq) |
| @@ -15,6 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | * GNU General Public License for more details. |
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 19 | + | |
| 18 | 20 | #include <linux/module.h> |
| 19 | 21 | #include <linux/i2c.h> |
| 20 | 22 | #include <linux/bcd.h> |
| @@ -90,7 +92,7 @@ struct s5m_rtc_info { · 69 unmodified lines | ||
| 90 | 92 | struct regmap *regmap; |
| 91 | 93 | struct rtc_device *rtc_dev; |
| 92 | 94 | int irq; |
| 93 | − int device_type; | |
| 95 | + enum sec_device_type device_type; | |
| 94 | 96 | int rtc_24hr_mode; |
| 95 | 97 | const struct s5m_rtc_reg_config *regs; |
| 96 | 98 | }; |
| @@ -146,7 +148,7 @@ static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data) · 49 unmodified lines | ||
| 146 | 148 | data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; |
| 147 | 149 | |
| 148 | 150 | if (tm->tm_year < 100) { |
| 149 | − pr_err("s5m8767 RTC cannot handle the year %d.\n", | |
| 151 | + pr_err("RTC cannot handle the year %d\n", | |
| 150 | 152 | 1900 + tm->tm_year); |
| 151 | 153 | return -EINVAL; |
| 152 | 154 | } else { |
| @@ -187,6 +189,7 @@ static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info, · 34 unmodified lines | ||
| 187 | 189 | val &= S5M_ALARM0_STATUS; |
| 188 | 190 | break; |
| 189 | 191 | case S2MPS14X: |
| 192 | + case S2MPS13X: | |
| 190 | 193 | ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2, |
| 191 | 194 | &val); |
| 192 | 195 | val &= S2MPS_ALARM0_STATUS; |
| @@ -252,6 +255,9 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) · 59 unmodified lines | ||
| 252 | 255 | case S2MPS14X: |
| 253 | 256 | data |= S2MPS_RTC_RUDR_MASK; |
| 254 | 257 | break; |
| 258 | + case S2MPS13X: | |
| 259 | + data |= S2MPS13_RTC_AUDR_MASK; | |
| 260 | + break; | |
| 255 | 261 | default: |
| 256 | 262 | return -EINVAL; |
| 257 | 263 | } |
| @@ -265,6 +271,11 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) · 7 unmodified lines | ||
| 265 | 271 | |
| 266 | 272 | ret = s5m8767_wait_for_udr_update(info); |
| 267 | 273 | |
| 274 | + /* On S2MPS13 the AUDR is not auto-cleared */ | |
| 275 | + if (info->device_type == S2MPS13X) | |
| 276 | + regmap_update_bits(info->regmap, info->regs->rtc_udr_update, | |
| 277 | + S2MPS13_RTC_AUDR_MASK, 0); | |
| 278 | + | |
| 268 | 279 | return ret; |
| 269 | 280 | } |
| 270 | 281 | |
| @@ -306,7 +317,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) · 35 unmodified lines | ||
| 306 | 317 | u8 data[info->regs->regs_count]; |
| 307 | 318 | int ret; |
| 308 | 319 | |
| 309 | − if (info->device_type == S2MPS14X) { | |
| 320 | + if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) { | |
| 310 | 321 | ret = regmap_update_bits(info->regmap, |
| 311 | 322 | info->regs->rtc_udr_update, |
| 312 | 323 | 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) · 16 unmodified lines | ||
| 329 | 340 | |
| 330 | 341 | case S5M8767X: |
| 331 | 342 | case S2MPS14X: |
| 343 | + case S2MPS13X: | |
| 332 | 344 | s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode); |
| 333 | 345 | break; |
| 334 | 346 | |
| @@ -355,6 +367,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) · 20 unmodified lines | ||
| 355 | 367 | break; |
| 356 | 368 | case S5M8767X: |
| 357 | 369 | case S2MPS14X: |
| 370 | + case S2MPS13X: | |
| 358 | 371 | ret = s5m8767_tm_to_data(tm, data); |
| 359 | 372 | break; |
| 360 | 373 | default: |
| @@ -402,6 +415,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) · 41 unmodified lines | ||
| 402 | 415 | |
| 403 | 416 | case S5M8767X: |
| 404 | 417 | case S2MPS14X: |
| 418 | + case S2MPS13X: | |
| 405 | 419 | s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); |
| 406 | 420 | alrm->enabled = 0; |
| 407 | 421 | for (i = 0; i < info->regs->regs_count; i++) { |
| @@ -450,6 +464,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) · 42 unmodified lines | ||
| 450 | 464 | |
| 451 | 465 | case S5M8767X: |
| 452 | 466 | case S2MPS14X: |
| 467 | + case S2MPS13X: | |
| 453 | 468 | for (i = 0; i < info->regs->regs_count; i++) |
| 454 | 469 | data[i] &= ~ALARM_ENABLE_MASK; |
| 455 | 470 | |
| @@ -494,6 +509,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) · 38 unmodified lines | ||
| 494 | 509 | |
| 495 | 510 | case S5M8767X: |
| 496 | 511 | case S2MPS14X: |
| 512 | + case S2MPS13X: | |
| 497 | 513 | data[RTC_SEC] |= ALARM_ENABLE_MASK; |
| 498 | 514 | data[RTC_MIN] |= ALARM_ENABLE_MASK; |
| 499 | 515 | data[RTC_HOUR] |= ALARM_ENABLE_MASK; |
| @@ -533,6 +549,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) · 33 unmodified lines | ||
| 533 | 549 | |
| 534 | 550 | case S5M8767X: |
| 535 | 551 | case S2MPS14X: |
| 552 | + case S2MPS13X: | |
| 536 | 553 | s5m8767_tm_to_data(&alrm->time, data); |
| 537 | 554 | break; |
| 538 | 555 | |
| @@ -615,6 +632,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) · 76 unmodified lines | ||
| 615 | 632 | break; |
| 616 | 633 | |
| 617 | 634 | case S2MPS14X: |
| 635 | + case S2MPS13X: | |
| 618 | 636 | data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); |
| 619 | 637 | ret = regmap_write(info->regmap, info->regs->ctrl, data[0]); |
| 620 | 638 | break; |
| @@ -650,8 +668,9 @@ static int s5m_rtc_probe(struct platform_device *pdev) · 29 unmodified lines | ||
| 650 | 668 | if (!info) |
| 651 | 669 | return -ENOMEM; |
| 652 | 670 | |
| 653 | − switch (pdata->device_type) { | |
| 671 | + switch (platform_get_device_id(pdev)->driver_data) { | |
| 654 | 672 | case S2MPS14X: |
| 673 | + case S2MPS13X: | |
| 655 | 674 | regmap_cfg = &s2mps14_rtc_regmap_config; |
| 656 | 675 | info->regs = &s2mps_rtc_regs; |
| 657 | 676 | alarm_irq = S2MPS14_IRQ_RTCA0; |
| @@ -667,7 +686,9 @@ static int s5m_rtc_probe(struct platform_device *pdev) · 9 unmodified lines | ||
| 667 | 686 | alarm_irq = S5M8767_IRQ_RTCA1; |
| 668 | 687 | break; |
| 669 | 688 | default: |
| 670 | − dev_err(&pdev->dev, "Device type is not supported by RTC driver\n"); | |
| 689 | + dev_err(&pdev->dev, | |
| 690 | + "Device type %lu is not supported by RTC driver\n", | |
| 691 | + platform_get_device_id(pdev)->driver_data); | |
| 671 | 692 | return -ENODEV; |
| 672 | 693 | } |
| 673 | 694 | |
| @@ -687,7 +708,7 @@ static int s5m_rtc_probe(struct platform_device *pdev) · 13 unmodified lines | ||
| 687 | 708 | |
| 688 | 709 | info->dev = &pdev->dev; |
| 689 | 710 | info->s5m87xx = s5m87xx; |
| 690 | − info->device_type = s5m87xx->device_type; | |
| 711 | + info->device_type = platform_get_device_id(pdev)->driver_data; | |
| 691 | 712 | |
| 692 | 713 | if (s5m87xx->irq_data) { |
| 693 | 714 | 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); · 78 unmodified lines | ||
| 772 | 793 | |
| 773 | 794 | static const struct platform_device_id s5m_rtc_id[] = { |
| 774 | 795 | { "s5m-rtc", S5M8767X }, |
| 796 | + { "s2mps13-rtc", S2MPS13X }, | |
| 775 | 797 | { "s2mps14-rtc", S2MPS14X }, |
| 776 | 798 | { }, |
| 777 | 799 | }; |
| @@ -42,6 +42,8 @@ · 41 unmodified lines | ||
| 42 | 42 | #define STMP3XXX_RTC_STAT 0x10 |
| 43 | 43 | #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 |
| 44 | 44 | #define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 |
| 45 | +#define STMP3XXX_RTC_STAT_XTAL32000_PRESENT 0x10000000 | |
| 46 | +#define STMP3XXX_RTC_STAT_XTAL32768_PRESENT 0x08000000 | |
| 45 | 47 | |
| 46 | 48 | #define STMP3XXX_RTC_SECONDS 0x30 |
| 47 | 49 | |
| @@ -52,9 +54,13 @@ · 4 unmodified lines | ||
| 52 | 54 | #define STMP3XXX_RTC_PERSISTENT0 0x60 |
| 53 | 55 | #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 |
| 54 | 56 | #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 |
| 55 | −#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 | |
| 56 | −#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 | |
| 57 | −#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 | |
| 57 | +#define STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE (1 << 0) | |
| 58 | +#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN (1 << 1) | |
| 59 | +#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN (1 << 2) | |
| 60 | +#define STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP (1 << 4) | |
| 61 | +#define STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP (1 << 5) | |
| 62 | +#define STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ (1 << 6) | |
| 63 | +#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE (1 << 7) | |
| 58 | 64 | |
| 59 | 65 | #define STMP3XXX_RTC_PERSISTENT1 0x70 |
| 60 | 66 | /* missing bitmask in headers */ |
| @@ -248,6 +254,9 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) · 187 unmodified lines | ||
| 248 | 254 | { |
| 249 | 255 | struct stmp3xxx_rtc_data *rtc_data; |
| 250 | 256 | struct resource *r; |
| 257 | + u32 rtc_stat; | |
| 258 | + u32 pers0_set, pers0_clr; | |
| 259 | + u32 crystalfreq = 0; | |
| 251 | 260 | int err; |
| 252 | 261 | |
| 253 | 262 | rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL); |
| @@ -268,8 +277,8 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) · 14 unmodified lines | ||
| 268 | 277 | |
| 269 | 278 | rtc_data->irq_alarm = platform_get_irq(pdev, 0); |
| 270 | 279 | |
| 271 | − if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & | |
| 272 | − STMP3XXX_RTC_STAT_RTC_PRESENT)) { | |
| 280 | + rtc_stat = readl(rtc_data->io + STMP3XXX_RTC_STAT); | |
| 281 | + if (!(rtc_stat & STMP3XXX_RTC_STAT_RTC_PRESENT)) { | |
| 273 | 282 | dev_err(&pdev->dev, "no device onboard\n"); |
| 274 | 283 | return -ENODEV; |
| 275 | 284 | } |
| @@ -282,9 +291,54 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 282 | 291 | return err; |
| 283 | 292 | } |
| 284 | 293 | |
| 294 | + /* | |
| 295 | + * Obviously the rtc needs a clock input to be able to run. | |
| 296 | + * This clock can be provided by an external 32k crystal. If that one is | |
| 297 | + * missing XTAL must not be disabled in suspend which consumes a | |
| 298 | + * lot of power. Normally the presence and exact frequency (supported | |
| 299 | + * are 32000 Hz and 32768 Hz) is detectable from fuses, but as reality | |
| 300 | + * proves these fuses are not blown correctly on all machines, so the | |
| 301 | + * frequency can be overridden in the device tree. | |
| 302 | + */ | |
| 303 | + if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32000_PRESENT) | |
| 304 | + crystalfreq = 32000; | |
| 305 | + else if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32768_PRESENT) | |
| 306 | + crystalfreq = 32768; | |
| 307 | + | |
| 308 | + of_property_read_u32(pdev->dev.of_node, "stmp,crystal-freq", | |
| 309 | + &crystalfreq); | |
| 310 | + | |
| 311 | + switch (crystalfreq) { | |
| 312 | + case 32000: | |
| 313 | + /* keep 32kHz crystal running in low-power mode */ | |
| 314 | + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ | | |
| 315 | + STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | | |
| 316 | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; | |
| 317 | + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP; | |
| 318 | + break; | |
| 319 | + case 32768: | |
| 320 | + /* keep 32.768kHz crystal running in low-power mode */ | |
| 321 | + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | | |
| 322 | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; | |
| 323 | + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP | | |
| 324 | + STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ; | |
| 325 | + break; | |
| 326 | + default: | |
| 327 | + dev_warn(&pdev->dev, | |
| 328 | + "invalid crystal-freq specified in device-tree. Assuming no crystal\n"); | |
| 329 | + /* fall-through */ | |
| 330 | + case 0: | |
| 331 | + /* keep XTAL on in low-power mode */ | |
| 332 | + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP; | |
| 333 | + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | | |
| 334 | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; | |
| 335 | + } | |
| 336 | + | |
| 337 | + writel(pers0_set, rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET); | |
| 338 | + | |
| 285 | 339 | writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | |
| 286 | 340 | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | |
| 287 | − STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, | |
| 341 | + STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE | pers0_clr, | |
| 288 | 342 | rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); |
| 289 | 343 | |
| 290 | 344 | writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | ||
| 18 | 18 | * 2 of the License, or (at your option) any later version. |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 22 | + | |
| 21 | 23 | #include <linux/kernel.h> |
| 22 | 24 | #include <linux/errno.h> |
| 23 | 25 | #include <linux/init.h> |
| @@ -145,8 +147,7 @@ static int twl_rtc_read_u8(u8 *data, u8 reg) · 121 unmodified lines | ||
| 145 | 147 | |
| 146 | 148 | ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg])); |
| 147 | 149 | if (ret < 0) |
| 148 | − pr_err("twl_rtc: Could not read TWL" | |
| 149 | − "register %X - error %d\n", reg, ret); | |
| 150 | + pr_err("Could not read TWL register %X - error %d\n", reg, ret); | |
| 150 | 151 | return ret; |
| 151 | 152 | } |
| 152 | 153 | |
| @@ -159,8 +160,8 @@ static int twl_rtc_write_u8(u8 data, u8 reg) · 6 unmodified lines | ||
| 159 | 160 | |
| 160 | 161 | ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg])); |
| 161 | 162 | if (ret < 0) |
| 162 | − pr_err("twl_rtc: Could not write TWL" | |
| 163 | − "register %X - error %d\n", reg, ret); | |
| 163 | + pr_err("Could not write TWL register %X - error %d\n", | |
| 164 | + reg, ret); | |
| 164 | 165 | return ret; |
| 165 | 166 | } |
| 166 | 167 | |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/rtc.h> |
| 23 | 23 | #include <linux/delay.h> |
| 24 | 24 | #include <linux/module.h> |
| 25 | +#include <linux/bitops.h> | |
| 25 | 26 | |
| 26 | 27 | #define DRV_VERSION "1.0.8" |
| 27 | 28 | |
| @@ -366,8 +367,7 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) · 338 unmodified lines | ||
| 366 | 367 | * perform sign extension. The formula is |
| 367 | 368 | * Catr = (atr * 0.25pF) + 11.00pF. |
| 368 | 369 | */ |
| 369 | − if (atr & 0x20) | |
| 370 | − atr |= 0xC0; | |
| 370 | + atr = sign_extend32(atr, 5); | |
| 371 | 371 | |
| 372 | 372 | dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __func__, atr, atr); |
| 373 | 373 | |
| @@ -1079,22 +1079,18 @@ bfad_start_ops(struct bfad_s *bfad) { · 1078 unmodified lines | ||
| 1079 | 1079 | int |
| 1080 | 1080 | bfad_worker(void *ptr) |
| 1081 | 1081 | { |
| 1082 | − struct bfad_s *bfad; | |
| 1083 | − unsigned long flags; | |
| 1084 | − | |
| 1085 | − bfad = (struct bfad_s *)ptr; | |
| 1086 | − | |
| 1087 | − while (!kthread_should_stop()) { | |
| 1082 | + struct bfad_s *bfad = ptr; | |
| 1083 | + unsigned long flags; | |
| 1088 | 1084 | |
| 1089 | − /* Send event BFAD_E_INIT_SUCCESS */ | |
| 1090 | − bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS); | |
| 1085 | + if (kthread_should_stop()) | |
| 1086 | + return 0; | |
| 1091 | 1087 | |
| 1092 | − spin_lock_irqsave(&bfad->bfad_lock, flags); | |
| 1093 | − bfad->bfad_tsk = NULL; | |
| 1094 | − spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
| 1088 | + /* Send event BFAD_E_INIT_SUCCESS */ | |
| 1089 | + bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS); | |
| 1095 | 1090 | |
| 1096 | − break; | |
| 1097 | − } | |
| 1091 | + spin_lock_irqsave(&bfad->bfad_lock, flags); | |
| 1092 | + bfad->bfad_tsk = NULL; | |
| 1093 | + spin_unlock_irqrestore(&bfad->bfad_lock, flags); | |
| 1098 | 1094 | |
| 1099 | 1095 | return 0; |
| 1100 | 1096 | } |
| @@ -86,6 +86,7 @@ int main(int argc, char **argv) · 85 unmodified lines | ||
| 86 | 86 | case 'j': |
| 87 | 87 | include_jump = 1; |
| 88 | 88 | break; |
| 89 | + default: | |
| 89 | 90 | return usage(); |
| 90 | 91 | } |
| 91 | 92 | } |
| @@ -61,6 +61,7 @@ adfs_fplus_read(struct super_block *sb, unsigned int id, unsigned int sz, struct · 60 unmodified lines | ||
| 61 | 61 | kcalloc(size, sizeof(struct buffer_head *), |
| 62 | 62 | GFP_KERNEL); |
| 63 | 63 | if (!bh_fplus) { |
| 64 | + ret = -ENOMEM; | |
| 64 | 65 | adfs_error(sb, "not enough memory for" |
| 65 | 66 | " dir object %X (%d blocks)", id, size); |
| 66 | 67 | goto out; |
| @@ -316,7 +316,7 @@ static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_di · 315 unmodified lines | ||
| 316 | 316 | dm = kmalloc(nzones * sizeof(*dm), GFP_KERNEL); |
| 317 | 317 | if (dm == NULL) { |
| 318 | 318 | adfs_error(sb, "not enough memory"); |
| 319 | − return NULL; | |
| 319 | + return ERR_PTR(-ENOMEM); | |
| 320 | 320 | } |
| 321 | 321 | |
| 322 | 322 | for (zone = 0; zone < nzones; zone++, map_addr++) { |
| @@ -349,7 +349,7 @@ error_free: · 26 unmodified lines | ||
| 349 | 349 | brelse(dm[zone].dm_bh); |
| 350 | 350 | |
| 351 | 351 | kfree(dm); |
| 352 | − return NULL; | |
| 352 | + return ERR_PTR(-EIO); | |
| 353 | 353 | } |
| 354 | 354 | |
| 355 | 355 | 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) · 14 unmodified lines | ||
| 370 | 370 | unsigned char *b_data; |
| 371 | 371 | struct adfs_sb_info *asb; |
| 372 | 372 | struct inode *root; |
| 373 | + int ret = -EINVAL; | |
| 373 | 374 | |
| 374 | 375 | sb->s_flags |= MS_NODIRATIME; |
| 375 | 376 | |
| @@ -391,6 +392,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) · 15 unmodified lines | ||
| 391 | 392 | sb_set_blocksize(sb, BLOCK_SIZE); |
| 392 | 393 | if (!(bh = sb_bread(sb, ADFS_DISCRECORD / BLOCK_SIZE))) { |
| 393 | 394 | adfs_error(sb, "unable to read superblock"); |
| 395 | + ret = -EIO; | |
| 394 | 396 | goto error; |
| 395 | 397 | } |
| 396 | 398 | |
| @@ -400,6 +402,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) · 3 unmodified lines | ||
| 400 | 402 | if (!silent) |
| 401 | 403 | printk("VFS: Can't find an adfs filesystem on dev " |
| 402 | 404 | "%s.\n", sb->s_id); |
| 405 | + ret = -EINVAL; | |
| 403 | 406 | goto error_free_bh; |
| 404 | 407 | } |
| 405 | 408 | |
| @@ -412,6 +415,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) · 6 unmodified lines | ||
| 412 | 415 | if (!silent) |
| 413 | 416 | printk("VPS: Can't find an adfs filesystem on dev " |
| 414 | 417 | "%s.\n", sb->s_id); |
| 418 | + ret = -EINVAL; | |
| 415 | 419 | goto error_free_bh; |
| 416 | 420 | } |
| 417 | 421 | |
| @@ -421,11 +425,13 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) · 3 unmodified lines | ||
| 421 | 425 | if (!bh) { |
| 422 | 426 | adfs_error(sb, "couldn't read superblock on " |
| 423 | 427 | "2nd try."); |
| 428 | + ret = -EIO; | |
| 424 | 429 | goto error; |
| 425 | 430 | } |
| 426 | 431 | b_data = bh->b_data + (ADFS_DISCRECORD % sb->s_blocksize); |
| 427 | 432 | if (adfs_checkbblk(b_data)) { |
| 428 | 433 | adfs_error(sb, "disc record mismatch, very weird!"); |
| 434 | + ret = -EINVAL; | |
| 429 | 435 | goto error_free_bh; |
| 430 | 436 | } |
| 431 | 437 | 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) · 1 unmodified line | ||
| 433 | 439 | if (!silent) |
| 434 | 440 | printk(KERN_ERR "VFS: Unsupported blocksize on dev " |
| 435 | 441 | "%s.\n", sb->s_id); |
| 442 | + ret = -EINVAL; | |
| 436 | 443 | goto error; |
| 437 | 444 | } |
| 438 | 445 | |
| @@ -447,10 +454,12 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) · 8 unmodified lines | ||
| 447 | 454 | asb->s_size = adfs_discsize(dr, sb->s_blocksize_bits); |
| 448 | 455 | asb->s_version = dr->format_version; |
| 449 | 456 | asb->s_log2sharesize = dr->log2sharesize; |
| 450 | − | |
| 457 | + | |
| 451 | 458 | asb->s_map = adfs_read_map(sb, dr); |
| 452 | − if (!asb->s_map) | |
| 459 | + if (IS_ERR(asb->s_map)) { | |
| 460 | + ret = PTR_ERR(asb->s_map); | |
| 453 | 461 | goto error_free_bh; |
| 462 | + } | |
| 454 | 463 | |
| 455 | 464 | brelse(bh); |
| 456 | 465 | |
| @@ -499,6 +508,7 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) · 42 unmodified lines | ||
| 499 | 508 | brelse(asb->s_map[i].dm_bh); |
| 500 | 509 | kfree(asb->s_map); |
| 501 | 510 | adfs_error(sb, "get root inode failed\n"); |
| 511 | + ret = -EIO; | |
| 502 | 512 | goto error; |
| 503 | 513 | } |
| 504 | 514 | return 0; |
| @@ -508,7 +518,7 @@ error_free_bh: · 3 unmodified lines | ||
| 508 | 518 | error: |
| 509 | 519 | sb->s_fs_info = NULL; |
| 510 | 520 | kfree(asb); |
| 511 | − return -EINVAL; | |
| 521 | + return ret; | |
| 512 | 522 | } |
| 513 | 523 | |
| 514 | 524 | static struct dentry *adfs_mount(struct file_system_type *fs_type, |
| @@ -106,18 +106,22 @@ struct affs_sb_info { · 105 unmodified lines | ||
| 106 | 106 | spinlock_t work_lock; /* protects sb_work and work_queued */ |
| 107 | 107 | }; |
| 108 | 108 | |
| 109 | −#define SF_INTL 0x0001 /* International filesystem. */ | |
| 110 | −#define SF_BM_VALID 0x0002 /* Bitmap is valid. */ | |
| 111 | −#define SF_IMMUTABLE 0x0004 /* Protection bits cannot be changed */ | |
| 112 | −#define SF_QUIET 0x0008 /* chmod errors will be not reported */ | |
| 113 | −#define SF_SETUID 0x0010 /* Ignore Amiga uid */ | |
| 114 | −#define SF_SETGID 0x0020 /* Ignore Amiga gid */ | |
| 115 | −#define SF_SETMODE 0x0040 /* Ignore Amiga protection bits */ | |
| 116 | −#define SF_MUFS 0x0100 /* Use MUFS uid/gid mapping */ | |
| 117 | −#define SF_OFS 0x0200 /* Old filesystem */ | |
| 118 | −#define SF_PREFIX 0x0400 /* Buffer for prefix is allocated */ | |
| 119 | −#define SF_VERBOSE 0x0800 /* Talk about fs when mounting */ | |
| 120 | −#define SF_NO_TRUNCATE 0x1000 /* Don't truncate filenames */ | |
| 109 | +#define AFFS_MOUNT_SF_INTL 0x0001 /* International filesystem. */ | |
| 110 | +#define AFFS_MOUNT_SF_BM_VALID 0x0002 /* Bitmap is valid. */ | |
| 111 | +#define AFFS_MOUNT_SF_IMMUTABLE 0x0004 /* Protection bits cannot be changed */ | |
| 112 | +#define AFFS_MOUNT_SF_QUIET 0x0008 /* chmod errors will be not reported */ | |
| 113 | +#define AFFS_MOUNT_SF_SETUID 0x0010 /* Ignore Amiga uid */ | |
| 114 | +#define AFFS_MOUNT_SF_SETGID 0x0020 /* Ignore Amiga gid */ | |
| 115 | +#define AFFS_MOUNT_SF_SETMODE 0x0040 /* Ignore Amiga protection bits */ | |
| 116 | +#define AFFS_MOUNT_SF_MUFS 0x0100 /* Use MUFS uid/gid mapping */ | |
| 117 | +#define AFFS_MOUNT_SF_OFS 0x0200 /* Old filesystem */ | |
| 118 | +#define AFFS_MOUNT_SF_PREFIX 0x0400 /* Buffer for prefix is allocated */ | |
| 119 | +#define AFFS_MOUNT_SF_VERBOSE 0x0800 /* Talk about fs when mounting */ | |
| 120 | +#define AFFS_MOUNT_SF_NO_TRUNCATE 0x1000 /* Don't truncate filenames */ | |
| 121 | + | |
| 122 | +#define affs_clear_opt(o, opt) (o &= ~AFFS_MOUNT_##opt) | |
| 123 | +#define affs_set_opt(o, opt) (o |= AFFS_MOUNT_##opt) | |
| 124 | +#define affs_test_opt(o, opt) ((o) & AFFS_MOUNT_##opt) | |
| 121 | 125 | |
| 122 | 126 | /* short cut to get to the affs specific sb data */ |
| 123 | 127 | static inline struct affs_sb_info *AFFS_SB(struct super_block *sb) |
| @@ -472,7 +472,8 @@ bool · 471 unmodified lines | ||
| 472 | 472 | affs_nofilenametruncate(const struct dentry *dentry) |
| 473 | 473 | { |
| 474 | 474 | struct inode *inode = dentry->d_inode; |
| 475 | − return AFFS_SB(inode->i_sb)->s_flags & SF_NO_TRUNCATE; | |
| 475 | + | |
| 476 | + return affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_NO_TRUNCATE); | |
| 476 | 477 | |
| 477 | 478 | } |
| 478 | 479 | |
| @@ -914,7 +914,7 @@ affs_truncate(struct inode *inode) · 913 unmodified lines | ||
| 914 | 914 | if (inode->i_size) { |
| 915 | 915 | AFFS_I(inode)->i_blkcnt = last_blk + 1; |
| 916 | 916 | AFFS_I(inode)->i_extcnt = ext + 1; |
| 917 | − if (AFFS_SB(sb)->s_flags & SF_OFS) { | |
| 917 | + if (affs_test_opt(AFFS_SB(sb)->s_flags, SF_OFS)) { | |
| 918 | 918 | struct buffer_head *bh = affs_bread_ino(inode, last_blk, 0); |
| 919 | 919 | u32 tmp; |
| 920 | 920 | if (IS_ERR(bh)) { |
| @@ -66,23 +66,23 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) · 65 unmodified lines | ||
| 66 | 66 | AFFS_I(inode)->i_lastalloc = 0; |
| 67 | 67 | AFFS_I(inode)->i_pa_cnt = 0; |
| 68 | 68 | |
| 69 | − if (sbi->s_flags & SF_SETMODE) | |
| 69 | + if (affs_test_opt(sbi->s_flags, SF_SETMODE)) | |
| 70 | 70 | inode->i_mode = sbi->s_mode; |
| 71 | 71 | else |
| 72 | 72 | inode->i_mode = prot_to_mode(prot); |
| 73 | 73 | |
| 74 | 74 | id = be16_to_cpu(tail->uid); |
| 75 | − if (id == 0 || sbi->s_flags & SF_SETUID) | |
| 75 | + if (id == 0 || affs_test_opt(sbi->s_flags, SF_SETUID)) | |
| 76 | 76 | inode->i_uid = sbi->s_uid; |
| 77 | − else if (id == 0xFFFF && sbi->s_flags & SF_MUFS) | |
| 77 | + else if (id == 0xFFFF && affs_test_opt(sbi->s_flags, SF_MUFS)) | |
| 78 | 78 | i_uid_write(inode, 0); |
| 79 | 79 | else |
| 80 | 80 | i_uid_write(inode, id); |
| 81 | 81 | |
| 82 | 82 | id = be16_to_cpu(tail->gid); |
| 83 | − if (id == 0 || sbi->s_flags & SF_SETGID) | |
| 83 | + if (id == 0 || affs_test_opt(sbi->s_flags, SF_SETGID)) | |
| 84 | 84 | inode->i_gid = sbi->s_gid; |
| 85 | − else if (id == 0xFFFF && sbi->s_flags & SF_MUFS) | |
| 85 | + else if (id == 0xFFFF && affs_test_opt(sbi->s_flags, SF_MUFS)) | |
| 86 | 86 | i_gid_write(inode, 0); |
| 87 | 87 | else |
| 88 | 88 | i_gid_write(inode, id); |
| @@ -94,7 +94,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) · 5 unmodified lines | ||
| 94 | 94 | /* fall through */ |
| 95 | 95 | case ST_USERDIR: |
| 96 | 96 | if (be32_to_cpu(tail->stype) == ST_USERDIR || |
| 97 | − sbi->s_flags & SF_SETMODE) { | |
| 97 | + affs_test_opt(sbi->s_flags, SF_SETMODE)) { | |
| 98 | 98 | if (inode->i_mode & S_IRUSR) |
| 99 | 99 | inode->i_mode |= S_IXUSR; |
| 100 | 100 | if (inode->i_mode & S_IRGRP) |
| @@ -133,7 +133,8 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) · 32 unmodified lines | ||
| 133 | 133 | } |
| 134 | 134 | if (tail->link_chain) |
| 135 | 135 | set_nlink(inode, 2); |
| 136 | − inode->i_mapping->a_ops = (sbi->s_flags & SF_OFS) ? &affs_aops_ofs : &affs_aops; | |
| 136 | + inode->i_mapping->a_ops = affs_test_opt(sbi->s_flags, SF_OFS) ? | |
| 137 | + &affs_aops_ofs : &affs_aops; | |
| 137 | 138 | inode->i_op = &affs_file_inode_operations; |
| 138 | 139 | inode->i_fop = &affs_file_operations; |
| 139 | 140 | break; |
| @@ -190,15 +191,15 @@ affs_write_inode(struct inode *inode, struct writeback_control *wbc) · 50 unmodified lines | ||
| 190 | 191 | if (!(inode->i_ino == AFFS_SB(sb)->s_root_block)) { |
| 191 | 192 | uid = i_uid_read(inode); |
| 192 | 193 | gid = i_gid_read(inode); |
| 193 | − if (AFFS_SB(sb)->s_flags & SF_MUFS) { | |
| 194 | + if (affs_test_opt(AFFS_SB(sb)->s_flags, SF_MUFS)) { | |
| 194 | 195 | if (uid == 0 || uid == 0xFFFF) |
| 195 | 196 | uid = uid ^ ~0; |
| 196 | 197 | if (gid == 0 || gid == 0xFFFF) |
| 197 | 198 | gid = gid ^ ~0; |
| 198 | 199 | } |
| 199 | − if (!(AFFS_SB(sb)->s_flags & SF_SETUID)) | |
| 200 | + if (!affs_test_opt(AFFS_SB(sb)->s_flags, SF_SETUID)) | |
| 200 | 201 | tail->uid = cpu_to_be16(uid); |
| 201 | − if (!(AFFS_SB(sb)->s_flags & SF_SETGID)) | |
| 202 | + if (!affs_test_opt(AFFS_SB(sb)->s_flags, SF_SETGID)) | |
| 202 | 203 | tail->gid = cpu_to_be16(gid); |
| 203 | 204 | } |
| 204 | 205 | } |
| @@ -221,11 +222,14 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr) · 16 unmodified lines | ||
| 221 | 222 | if (error) |
| 222 | 223 | goto out; |
| 223 | 224 | |
| 224 | − if (((attr->ia_valid & ATTR_UID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETUID)) || | |
| 225 | − ((attr->ia_valid & ATTR_GID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETGID)) || | |
| 225 | + if (((attr->ia_valid & ATTR_UID) && | |
| 226 | + affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_SETUID)) || | |
| 227 | + ((attr->ia_valid & ATTR_GID) && | |
| 228 | + affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_SETGID)) || | |
| 226 | 229 | ((attr->ia_valid & ATTR_MODE) && |
| 227 | − (AFFS_SB(inode->i_sb)->s_flags & (SF_SETMODE | SF_IMMUTABLE)))) { | |
| 228 | − if (!(AFFS_SB(inode->i_sb)->s_flags & SF_QUIET)) | |
| 230 | + (AFFS_SB(inode->i_sb)->s_flags & | |
| 231 | + (AFFS_MOUNT_SF_SETMODE | AFFS_MOUNT_SF_IMMUTABLE)))) { | |
| 232 | + if (!affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_QUIET)) | |
| 229 | 233 | error = -EPERM; |
| 230 | 234 | goto out; |
| 231 | 235 | } |
| @@ -53,7 +53,8 @@ affs_intl_toupper(int ch) · 52 unmodified lines | ||
| 53 | 53 | static inline toupper_t |
| 54 | 54 | affs_get_toupper(struct super_block *sb) |
| 55 | 55 | { |
| 56 | − return AFFS_SB(sb)->s_flags & SF_INTL ? affs_intl_toupper : affs_toupper; | |
| 56 | + return affs_test_opt(AFFS_SB(sb)->s_flags, SF_INTL) ? | |
| 57 | + affs_intl_toupper : affs_toupper; | |
| 57 | 58 | } |
| 58 | 59 | |
| 59 | 60 | /* |
| @@ -275,7 +276,8 @@ affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) · 215 unmodified lines | ||
| 275 | 276 | |
| 276 | 277 | inode->i_op = &affs_file_inode_operations; |
| 277 | 278 | inode->i_fop = &affs_file_operations; |
| 278 | − inode->i_mapping->a_ops = (AFFS_SB(sb)->s_flags & SF_OFS) ? &affs_aops_ofs : &affs_aops; | |
| 279 | + inode->i_mapping->a_ops = affs_test_opt(AFFS_SB(sb)->s_flags, SF_OFS) ? | |
| 280 | + &affs_aops_ofs : &affs_aops; | |
| 279 | 281 | error = affs_add_entry(dir, inode, dentry, ST_FILE); |
| 280 | 282 | if (error) { |
| 281 | 283 | clear_nlink(inode); |
| @@ -227,22 +227,22 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved, · 226 unmodified lines | ||
| 227 | 227 | if (match_octal(&args[0], &option)) |
| 228 | 228 | return 0; |
| 229 | 229 | *mode = option & 0777; |
| 230 | − *mount_opts |= SF_SETMODE; | |
| 230 | + affs_set_opt(*mount_opts, SF_SETMODE); | |
| 231 | 231 | break; |
| 232 | 232 | case Opt_mufs: |
| 233 | − *mount_opts |= SF_MUFS; | |
| 233 | + affs_set_opt(*mount_opts, SF_MUFS); | |
| 234 | 234 | break; |
| 235 | 235 | case Opt_notruncate: |
| 236 | − *mount_opts |= SF_NO_TRUNCATE; | |
| 236 | + affs_set_opt(*mount_opts, SF_NO_TRUNCATE); | |
| 237 | 237 | break; |
| 238 | 238 | case Opt_prefix: |
| 239 | 239 | *prefix = match_strdup(&args[0]); |
| 240 | 240 | if (!*prefix) |
| 241 | 241 | return 0; |
| 242 | − *mount_opts |= SF_PREFIX; | |
| 242 | + affs_set_opt(*mount_opts, SF_PREFIX); | |
| 243 | 243 | break; |
| 244 | 244 | case Opt_protect: |
| 245 | − *mount_opts |= SF_IMMUTABLE; | |
| 245 | + affs_set_opt(*mount_opts, SF_IMMUTABLE); | |
| 246 | 246 | break; |
| 247 | 247 | case Opt_reserved: |
| 248 | 248 | if (match_int(&args[0], reserved)) |
| @@ -258,7 +258,7 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved, · 9 unmodified lines | ||
| 258 | 258 | *gid = make_kgid(current_user_ns(), option); |
| 259 | 259 | if (!gid_valid(*gid)) |
| 260 | 260 | return 0; |
| 261 | − *mount_opts |= SF_SETGID; | |
| 261 | + affs_set_opt(*mount_opts, SF_SETGID); | |
| 262 | 262 | break; |
| 263 | 263 | case Opt_setuid: |
| 264 | 264 | if (match_int(&args[0], &option)) |
| @@ -266,10 +266,10 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved, · 1 unmodified line | ||
| 266 | 266 | *uid = make_kuid(current_user_ns(), option); |
| 267 | 267 | if (!uid_valid(*uid)) |
| 268 | 268 | return 0; |
| 269 | − *mount_opts |= SF_SETUID; | |
| 269 | + affs_set_opt(*mount_opts, SF_SETUID); | |
| 270 | 270 | break; |
| 271 | 271 | case Opt_verbose: |
| 272 | − *mount_opts |= SF_VERBOSE; | |
| 272 | + affs_set_opt(*mount_opts, SF_VERBOSE); | |
| 273 | 273 | break; |
| 274 | 274 | case Opt_volume: { |
| 275 | 275 | char *vol = match_strdup(&args[0]); |
| @@ -435,30 +435,31 @@ got_root: · 159 unmodified lines | ||
| 435 | 435 | case MUFS_FS: |
| 436 | 436 | case MUFS_INTLFFS: |
| 437 | 437 | case MUFS_DCFFS: |
| 438 | − sbi->s_flags |= SF_MUFS; | |
| 438 | + affs_set_opt(sbi->s_flags, SF_MUFS); | |
| 439 | 439 | /* fall thru */ |
| 440 | 440 | case FS_INTLFFS: |
| 441 | 441 | case FS_DCFFS: |
| 442 | − sbi->s_flags |= SF_INTL; | |
| 442 | + affs_set_opt(sbi->s_flags, SF_INTL); | |
| 443 | 443 | break; |
| 444 | 444 | case MUFS_FFS: |
| 445 | − sbi->s_flags |= SF_MUFS; | |
| 445 | + affs_set_opt(sbi->s_flags, SF_MUFS); | |
| 446 | 446 | break; |
| 447 | 447 | case FS_FFS: |
| 448 | 448 | break; |
| 449 | 449 | case MUFS_OFS: |
| 450 | − sbi->s_flags |= SF_MUFS; | |
| 450 | + affs_set_opt(sbi->s_flags, SF_MUFS); | |
| 451 | 451 | /* fall thru */ |
| 452 | 452 | case FS_OFS: |
| 453 | − sbi->s_flags |= SF_OFS; | |
| 453 | + affs_set_opt(sbi->s_flags, SF_OFS); | |
| 454 | 454 | sb->s_flags |= MS_NOEXEC; |
| 455 | 455 | break; |
| 456 | 456 | case MUFS_DCOFS: |
| 457 | 457 | case MUFS_INTLOFS: |
| 458 | − sbi->s_flags |= SF_MUFS; | |
| 458 | + affs_set_opt(sbi->s_flags, SF_MUFS); | |
| 459 | 459 | case FS_DCOFS: |
| 460 | 460 | case FS_INTLOFS: |
| 461 | − sbi->s_flags |= SF_INTL | SF_OFS; | |
| 461 | + affs_set_opt(sbi->s_flags, SF_INTL); | |
| 462 | + affs_set_opt(sbi->s_flags, SF_OFS); | |
| 462 | 463 | sb->s_flags |= MS_NOEXEC; |
| 463 | 464 | break; |
| 464 | 465 | default: |
| @@ -467,7 +468,7 @@ got_root: · 2 unmodified lines | ||
| 467 | 468 | return -EINVAL; |
| 468 | 469 | } |
| 469 | 470 | |
| 470 | − if (mount_flags & SF_VERBOSE) { | |
| 471 | + if (affs_test_opt(mount_flags, SF_VERBOSE)) { | |
| 471 | 472 | u8 len = AFFS_ROOT_TAIL(sb, root_bh)->disk_name[0]; |
| 472 | 473 | pr_notice("Mounting volume \"%.*s\": Type=%.3s\\%c, Blocksize=%d\n", |
| 473 | 474 | len > 31 ? 31 : len, |
| @@ -478,7 +479,7 @@ got_root: · 4 unmodified lines | ||
| 478 | 479 | sb->s_flags |= MS_NODEV | MS_NOSUID; |
| 479 | 480 | |
| 480 | 481 | sbi->s_data_blksize = sb->s_blocksize; |
| 481 | − if (sbi->s_flags & SF_OFS) | |
| 482 | + if (affs_test_opt(sbi->s_flags, SF_OFS)) | |
| 482 | 483 | sbi->s_data_blksize -= 24; |
| 483 | 484 | |
| 484 | 485 | tmp_flags = sb->s_flags; |
| @@ -493,7 +494,7 @@ got_root: · 8 unmodified lines | ||
| 493 | 494 | if (IS_ERR(root_inode)) |
| 494 | 495 | return PTR_ERR(root_inode); |
| 495 | 496 | |
| 496 | − if (AFFS_SB(sb)->s_flags & SF_INTL) | |
| 497 | + if (affs_test_opt(AFFS_SB(sb)->s_flags, SF_INTL)) | |
| 497 | 498 | sb->s_d_op = &affs_intl_dentry_operations; |
| 498 | 499 | else |
| 499 | 500 | sb->s_d_op = &affs_dentry_operations; |
| @@ -520,10 +521,14 @@ affs_remount(struct super_block *sb, int *flags, char *data) · 20 unmodified lines | ||
| 520 | 521 | int root_block; |
| 521 | 522 | unsigned long mount_flags; |
| 522 | 523 | int res = 0; |
| 523 | − char *new_opts = kstrdup(data, GFP_KERNEL); | |
| 524 | + char *new_opts; | |
| 524 | 525 | char volume[32]; |
| 525 | 526 | char *prefix = NULL; |
| 526 | 527 | |
| 528 | + new_opts = kstrdup(data, GFP_KERNEL); | |
| 529 | + if (!new_opts) | |
| 530 | + return -ENOMEM; | |
| 531 | + | |
| 527 | 532 | pr_debug("%s(flags=0x%x,opts=\"%s\")\n", __func__, *flags, data); |
| 528 | 533 | |
| 529 | 534 | sync_filesystem(sb); |
| @@ -19,16 +19,16 @@ typedef u64 befs_blocknr_t; · 18 unmodified lines | ||
| 19 | 19 | * BeFS in memory structures |
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | −typedef struct befs_mount_options { | |
| 22 | +struct befs_mount_options { | |
| 23 | 23 | kgid_t gid; |
| 24 | 24 | kuid_t uid; |
| 25 | 25 | int use_gid; |
| 26 | 26 | int use_uid; |
| 27 | 27 | int debug; |
| 28 | 28 | char *iocharset; |
| 29 | −} befs_mount_options; | |
| 29 | +}; | |
| 30 | 30 | |
| 31 | −typedef struct befs_sb_info { | |
| 31 | +struct befs_sb_info { | |
| 32 | 32 | u32 magic1; |
| 33 | 33 | u32 block_size; |
| 34 | 34 | u32 block_shift; |
| @@ -52,12 +52,11 @@ typedef struct befs_sb_info { · 17 unmodified lines | ||
| 52 | 52 | befs_inode_addr indices; |
| 53 | 53 | u32 magic3; |
| 54 | 54 | |
| 55 | − befs_mount_options mount_opts; | |
| 55 | + struct befs_mount_options mount_opts; | |
| 56 | 56 | struct nls_table *nls; |
| 57 | +}; | |
| 57 | 58 | |
| 58 | −} befs_sb_info; | |
| 59 | − | |
| 60 | −typedef struct befs_inode_info { | |
| 59 | +struct befs_inode_info { | |
| 61 | 60 | u32 i_flags; |
| 62 | 61 | u32 i_type; |
| 63 | 62 | |
| @@ -71,8 +70,7 @@ typedef struct befs_inode_info { · 7 unmodified lines | ||
| 71 | 70 | } i_data; |
| 72 | 71 | |
| 73 | 72 | struct inode vfs_inode; |
| 74 | − | |
| 75 | −} befs_inode_info; | |
| 73 | +}; | |
| 76 | 74 | |
| 77 | 75 | enum befs_err { |
| 78 | 76 | BEFS_OK, |
| @@ -105,13 +103,13 @@ void befs_dump_index_node(const struct super_block *sb, befs_btree_nodehead *); · 26 unmodified lines | ||
| 105 | 103 | /* Gets a pointer to the private portion of the super_block |
| 106 | 104 | * structure from the public part |
| 107 | 105 | */ |
| 108 | −static inline befs_sb_info * | |
| 106 | +static inline struct befs_sb_info * | |
| 109 | 107 | BEFS_SB(const struct super_block *super) |
| 110 | 108 | { |
| 111 | − return (befs_sb_info *) super->s_fs_info; | |
| 109 | + return (struct befs_sb_info *) super->s_fs_info; | |
| 112 | 110 | } |
| 113 | 111 | |
| 114 | −static inline befs_inode_info * | |
| 112 | +static inline struct befs_inode_info * | |
| 115 | 113 | BEFS_I(const struct inode *inode) |
| 116 | 114 | { |
| 117 | 115 | 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) · 167 unmodified lines | ||
| 168 | 168 | befs_blocknr_t blocks; |
| 169 | 169 | befs_blocknr_t datablocks; /* File data blocks */ |
| 170 | 170 | befs_blocknr_t metablocks; /* FS metadata blocks */ |
| 171 | − befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 171 | + struct befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 172 | 172 | |
| 173 | 173 | befs_debug(sb, "---> %s", __func__); |
| 174 | 174 | |
| @@ -428,7 +428,7 @@ befs_find_brun_dblindirect(struct super_block *sb, · 253 unmodified lines | ||
| 428 | 428 | struct buffer_head *indir_block; |
| 429 | 429 | befs_block_run indir_run; |
| 430 | 430 | befs_disk_inode_addr *iaddr_array = NULL; |
| 431 | − befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 431 | + struct befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 432 | 432 | |
| 433 | 433 | befs_blocknr_t indir_start_blk = |
| 434 | 434 | data->max_indirect_range >> befs_sb->block_shift; |
| @@ -28,7 +28,7 @@ befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) · 27 unmodified lines | ||
| 28 | 28 | { |
| 29 | 29 | struct buffer_head *bh = NULL; |
| 30 | 30 | befs_blocknr_t block = 0; |
| 31 | − befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 31 | + struct befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 32 | 32 | |
| 33 | 33 | befs_debug(sb, "---> Enter %s " |
| 34 | 34 | "[%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, · 50 unmodified lines | ||
| 51 | 51 | static void befs_put_super(struct super_block *); |
| 52 | 52 | static int befs_remount(struct super_block *, int *, char *); |
| 53 | 53 | static int befs_statfs(struct dentry *, struct kstatfs *); |
| 54 | −static int parse_options(char *, befs_mount_options *); | |
| 54 | +static int parse_options(char *, struct befs_mount_options *); | |
| 55 | 55 | |
| 56 | 56 | static const struct super_operations befs_sops = { |
| 57 | 57 | .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) · 246 unmodified lines | ||
| 304 | 304 | { |
| 305 | 305 | struct buffer_head *bh = NULL; |
| 306 | 306 | befs_inode *raw_inode = NULL; |
| 307 | − | |
| 308 | − befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 309 | − befs_inode_info *befs_ino = NULL; | |
| 307 | + struct befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 308 | + struct befs_inode_info *befs_ino = NULL; | |
| 310 | 309 | struct inode *inode; |
| 311 | 310 | long ret = -EIO; |
| 312 | 311 | |
| @@ -472,7 +471,7 @@ static void * · 159 unmodified lines | ||
| 472 | 471 | befs_follow_link(struct dentry *dentry, struct nameidata *nd) |
| 473 | 472 | { |
| 474 | 473 | struct super_block *sb = dentry->d_sb; |
| 475 | − befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); | |
| 474 | + struct befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); | |
| 476 | 475 | befs_data_stream *data = &befs_ino->i_data.ds; |
| 477 | 476 | befs_off_t len = data->size; |
| 478 | 477 | char *link; |
| @@ -502,7 +501,8 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd) · 23 unmodified lines | ||
| 502 | 501 | static void * |
| 503 | 502 | befs_fast_follow_link(struct dentry *dentry, struct nameidata *nd) |
| 504 | 503 | { |
| 505 | − befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); | |
| 504 | + struct befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); | |
| 505 | + | |
| 506 | 506 | nd_set_link(nd, befs_ino->i_data.symlink); |
| 507 | 507 | return NULL; |
| 508 | 508 | } |
| @@ -669,7 +669,7 @@ static const match_table_t befs_tokens = { · 160 unmodified lines | ||
| 669 | 669 | }; |
| 670 | 670 | |
| 671 | 671 | static int |
| 672 | −parse_options(char *options, befs_mount_options * opts) | |
| 672 | +parse_options(char *options, struct befs_mount_options *opts) | |
| 673 | 673 | { |
| 674 | 674 | char *p; |
| 675 | 675 | substring_t args[MAX_OPT_ARGS]; |
| @@ -769,7 +769,7 @@ static int · 93 unmodified lines | ||
| 769 | 769 | befs_fill_super(struct super_block *sb, void *data, int silent) |
| 770 | 770 | { |
| 771 | 771 | struct buffer_head *bh; |
| 772 | − befs_sb_info *befs_sb; | |
| 772 | + struct befs_sb_info *befs_sb; | |
| 773 | 773 | befs_super_block *disk_sb; |
| 774 | 774 | struct inode *root; |
| 775 | 775 | long ret = -EINVAL; |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | int |
| 25 | 25 | befs_load_sb(struct super_block *sb, befs_super_block * disk_sb) |
| 26 | 26 | { |
| 27 | − befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 27 | + struct befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 28 | 28 | |
| 29 | 29 | /* Check the byte order of the filesystem */ |
| 30 | 30 | 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) · 28 unmodified lines | ||
| 59 | 59 | int |
| 60 | 60 | befs_check_sb(struct super_block *sb) |
| 61 | 61 | { |
| 62 | − befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 62 | + struct befs_sb_info *befs_sb = BEFS_SB(sb); | |
| 63 | 63 | |
| 64 | 64 | /* Check magic headers of super block */ |
| 65 | 65 | if ((befs_sb->magic1 != BEFS_SUPER_MAGIC1) |
| @@ -86,7 +86,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | inode = new_inode(s); |
| 88 | 88 | if (!inode) |
| 89 | − return -ENOSPC; | |
| 89 | + return -ENOMEM; | |
| 90 | 90 | mutex_lock(&info->bfs_lock); |
| 91 | 91 | ino = find_first_zero_bit(info->si_imap, info->si_lasti + 1); |
| 92 | 92 | if (ino > info->si_lasti) { |
| @@ -293,7 +293,7 @@ static int bfs_add_entry(struct inode *dir, const unsigned char *name, · 200 unmodified lines | ||
| 293 | 293 | for (block = sblock; block <= eblock; block++) { |
| 294 | 294 | bh = sb_bread(dir->i_sb, block); |
| 295 | 295 | if (!bh) |
| 296 | − return -ENOSPC; | |
| 296 | + return -EIO; | |
| 297 | 297 | for (off = 0; off < BFS_BSIZE; off += BFS_DIRENT_SIZE) { |
| 298 | 298 | de = (struct bfs_dirent *)(bh->b_data + off); |
| 299 | 299 | if (!de->ino) { |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 11 | 11 | |
| 12 | +#include <linux/kernel.h> | |
| 12 | 13 | #include <linux/module.h> |
| 13 | 14 | #include <linux/init.h> |
| 14 | 15 | #include <linux/sched.h> |
| @@ -521,9 +522,8 @@ static int parse_command(const char __user *buffer, size_t count) · 506 unmodified lines | ||
| 521 | 522 | |
| 522 | 523 | static void entry_status(Node *e, char *page) |
| 523 | 524 | { |
| 524 | − char *dp; | |
| 525 | − char *status = "disabled"; | |
| 526 | − const char *flags = "flags: "; | |
| 525 | + char *dp = page; | |
| 526 | + const char *status = "disabled"; | |
| 527 | 527 | |
| 528 | 528 | if (test_bit(Enabled, &e->flags)) |
| 529 | 529 | status = "enabled"; |
| @@ -533,12 +533,10 @@ static void entry_status(Node *e, char *page) · 3 unmodified lines | ||
| 533 | 533 | return; |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | − sprintf(page, "%s\ninterpreter %s\n", status, e->interpreter); | |
| 537 | − dp = page + strlen(page); | |
| 536 | + dp += sprintf(dp, "%s\ninterpreter %s\n", status, e->interpreter); | |
| 538 | 537 | |
| 539 | 538 | /* print the special flags */ |
| 540 | − sprintf(dp, "%s", flags); | |
| 541 | − dp += strlen(flags); | |
| 539 | + dp += sprintf(dp, "flags: "); | |
| 542 | 540 | if (e->flags & MISC_FMT_PRESERVE_ARGV0) |
| 543 | 541 | *dp++ = 'P'; |
| 544 | 542 | if (e->flags & MISC_FMT_OPEN_BINARY) |
| @@ -550,21 +548,11 @@ static void entry_status(Node *e, char *page) · 5 unmodified lines | ||
| 550 | 548 | if (!test_bit(Magic, &e->flags)) { |
| 551 | 549 | sprintf(dp, "extension .%s\n", e->magic); |
| 552 | 550 | } else { |
| 553 | − int i; | |
| 554 | − | |
| 555 | − sprintf(dp, "offset %i\nmagic ", e->offset); | |
| 556 | − dp = page + strlen(page); | |
| 557 | − for (i = 0; i < e->size; i++) { | |
| 558 | − sprintf(dp, "%02x", 0xff & (int) (e->magic[i])); | |
| 559 | − dp += 2; | |
| 560 | − } | |
| 551 | + dp += sprintf(dp, "offset %i\nmagic ", e->offset); | |
| 552 | + dp = bin2hex(dp, e->magic, e->size); | |
| 561 | 553 | if (e->mask) { |
| 562 | − sprintf(dp, "\nmask "); | |
| 563 | − dp += 6; | |
| 564 | − for (i = 0; i < e->size; i++) { | |
| 565 | − sprintf(dp, "%02x", 0xff & (int) (e->mask[i])); | |
| 566 | − dp += 2; | |
| 567 | − } | |
| 554 | + dp += sprintf(dp, "\nmask "); | |
| 555 | + dp = bin2hex(dp, e->mask, e->size); | |
| 568 | 556 | } |
| 569 | 557 | *dp++ = '\n'; |
| 570 | 558 | *dp = '\0'; |
| @@ -926,10 +926,14 @@ static int de_thread(struct task_struct *tsk) · 925 unmodified lines | ||
| 926 | 926 | if (!thread_group_leader(tsk)) { |
| 927 | 927 | struct task_struct *leader = tsk->group_leader; |
| 928 | 928 | |
| 929 | − sig->notify_count = -1; /* for exit_notify() */ | |
| 930 | 929 | for (;;) { |
| 931 | 930 | threadgroup_change_begin(tsk); |
| 932 | 931 | write_lock_irq(&tasklist_lock); |
| 932 | + /* | |
| 933 | + * Do this under tasklist_lock to ensure that | |
| 934 | + * exit_notify() can't miss ->group_exit_task | |
| 935 | + */ | |
| 936 | + sig->notify_count = -1; | |
| 933 | 937 | if (likely(leader->exit_state)) |
| 934 | 938 | break; |
| 935 | 939 | __set_current_state(TASK_KILLABLE); |
| @@ -1078,7 +1082,13 @@ int flush_old_exec(struct linux_binprm * bprm) · 142 unmodified lines | ||
| 1078 | 1082 | if (retval) |
| 1079 | 1083 | goto out; |
| 1080 | 1084 | |
| 1085 | + /* | |
| 1086 | + * Must be called _before_ exec_mmap() as bprm->mm is | |
| 1087 | + * not visibile until then. This also enables the update | |
| 1088 | + * to be lockless. | |
| 1089 | + */ | |
| 1081 | 1090 | set_mm_exe_file(bprm->mm, bprm->file); |
| 1091 | + | |
| 1082 | 1092 | /* |
| 1083 | 1093 | * Release all of the old mmap stuff |
| 1084 | 1094 | */ |
| @@ -8,9 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | * May 1999. AV. Fixed the bogosity with FAT32 (read "FAT28"). Fscking lusers. |
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | −#include <linux/fs.h> | |
| 12 | 11 | #include <linux/slab.h> |
| 13 | −#include <linux/buffer_head.h> | |
| 14 | 12 | #include "fat.h" |
| 15 | 13 | |
| 16 | 14 | /* this must be > 0. */ |
| @@ -13,13 +13,9 @@ · 12 unmodified lines | ||
| 13 | 13 | * Short name translation 1999, 2001 by Wolfram Pienkoss <wp@bszh.de> |
| 14 | 14 | */ |
| 15 | 15 | |
| 16 | −#include <linux/module.h> | |
| 17 | 16 | #include <linux/slab.h> |
| 18 | −#include <linux/time.h> | |
| 19 | −#include <linux/buffer_head.h> | |
| 20 | 17 | #include <linux/compat.h> |
| 21 | 18 | #include <linux/uaccess.h> |
| 22 | −#include <linux/kernel.h> | |
| 23 | 19 | #include "fat.h" |
| 24 | 20 | |
| 25 | 21 | /* |
| @@ -2,11 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | #define _FAT_H |
| 3 | 3 | |
| 4 | 4 | #include <linux/buffer_head.h> |
| 5 | −#include <linux/string.h> | |
| 6 | 5 | #include <linux/nls.h> |
| 7 | −#include <linux/fs.h> | |
| 8 | 6 | #include <linux/hash.h> |
| 9 | −#include <linux/mutex.h> | |
| 10 | 7 | #include <linux/ratelimit.h> |
| 11 | 8 | #include <linux/msdos_fs.h> |
| 12 | 9 | |
| @@ -66,7 +63,7 @@ struct msdos_sb_info { · 53 unmodified lines | ||
| 66 | 63 | unsigned short sec_per_clus; /* sectors/cluster */ |
| 67 | 64 | unsigned short cluster_bits; /* log2(cluster_size) */ |
| 68 | 65 | unsigned int cluster_size; /* cluster size */ |
| 69 | − unsigned char fats, fat_bits; /* number of FATs, FAT bits (12 or 16) */ | |
| 66 | + unsigned char fats, fat_bits; /* number of FATs, FAT bits (12,16 or 32) */ | |
| 70 | 67 | unsigned short fat_start; |
| 71 | 68 | unsigned long fat_length; /* FAT start & length (sec.) */ |
| 72 | 69 | unsigned long dir_start; |
| @@ -3,9 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | * Released under GPL v2. |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | −#include <linux/module.h> | |
| 7 | −#include <linux/fs.h> | |
| 8 | −#include <linux/msdos_fs.h> | |
| 9 | 6 | #include <linux/blkdev.h> |
| 10 | 7 | #include "fat.h" |
| 11 | 8 | |
| @@ -10,10 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/module.h> |
| 11 | 11 | #include <linux/compat.h> |
| 12 | 12 | #include <linux/mount.h> |
| 13 | −#include <linux/time.h> | |
| 14 | −#include <linux/buffer_head.h> | |
| 15 | −#include <linux/writeback.h> | |
| 16 | −#include <linux/backing-dev.h> | |
| 17 | 13 | #include <linux/blkdev.h> |
| 18 | 14 | #include <linux/fsnotify.h> |
| 19 | 15 | #include <linux/security.h> |
| @@ -11,20 +11,12 @@ · 10 unmodified lines | ||
| 11 | 11 | */ |
| 12 | 12 | |
| 13 | 13 | #include <linux/module.h> |
| 14 | −#include <linux/init.h> | |
| 15 | −#include <linux/time.h> | |
| 16 | −#include <linux/slab.h> | |
| 17 | −#include <linux/seq_file.h> | |
| 18 | 14 | #include <linux/pagemap.h> |
| 19 | 15 | #include <linux/mpage.h> |
| 20 | −#include <linux/buffer_head.h> | |
| 21 | −#include <linux/mount.h> | |
| 22 | 16 | #include <linux/vfs.h> |
| 17 | +#include <linux/seq_file.h> | |
| 23 | 18 | #include <linux/parser.h> |
| 24 | 19 | #include <linux/uio.h> |
| 25 | −#include <linux/writeback.h> | |
| 26 | −#include <linux/log2.h> | |
| 27 | −#include <linux/hash.h> | |
| 28 | 20 | #include <linux/blkdev.h> |
| 29 | 21 | #include <asm/unaligned.h> |
| 30 | 22 | #include "fat.h" |
| @@ -1278,8 +1270,7 @@ out: · 1247 unmodified lines | ||
| 1278 | 1270 | |
| 1279 | 1271 | static int fat_read_root(struct inode *inode) |
| 1280 | 1272 | { |
| 1281 | − struct super_block *sb = inode->i_sb; | |
| 1282 | − struct msdos_sb_info *sbi = MSDOS_SB(sb); | |
| 1273 | + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | |
| 1283 | 1274 | int error; |
| 1284 | 1275 | |
| 1285 | 1276 | MSDOS_I(inode)->i_pos = MSDOS_ROOT_INO; |
| @@ -6,10 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru) |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | −#include <linux/module.h> | |
| 10 | −#include <linux/fs.h> | |
| 11 | −#include <linux/buffer_head.h> | |
| 12 | −#include <linux/time.h> | |
| 13 | 9 | #include "fat.h" |
| 14 | 10 | |
| 15 | 11 | /* |
| @@ -7,8 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #include <linux/module.h> |
| 10 | −#include <linux/time.h> | |
| 11 | −#include <linux/buffer_head.h> | |
| 12 | 10 | #include "fat.h" |
| 13 | 11 | |
| 14 | 12 | /* Characters that are undesirable in an MS-DOS file name */ |
| @@ -16,10 +16,8 @@ · 15 unmodified lines | ||
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | 18 | #include <linux/module.h> |
| 19 | −#include <linux/jiffies.h> | |
| 20 | 19 | #include <linux/ctype.h> |
| 21 | 20 | #include <linux/slab.h> |
| 22 | −#include <linux/buffer_head.h> | |
| 23 | 21 | #include <linux/namei.h> |
| 24 | 22 | #include "fat.h" |
| 25 | 23 | |
| @@ -638,8 +638,7 @@ static struct file *__fget(unsigned int fd, fmode_t mask) · 637 unmodified lines | ||
| 638 | 638 | file = fcheck_files(files, fd); |
| 639 | 639 | if (file) { |
| 640 | 640 | /* File object ref couldn't be taken */ |
| 641 | − if ((file->f_mode & mask) || | |
| 642 | − !atomic_long_inc_not_zero(&file->f_count)) | |
| 641 | + if ((file->f_mode & mask) || !get_file_rcu(file)) | |
| 643 | 642 | file = NULL; |
| 644 | 643 | } |
| 645 | 644 | rcu_read_unlock(); |
| @@ -197,7 +197,7 @@ static int hfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, · 196 unmodified lines | ||
| 197 | 197 | |
| 198 | 198 | inode = hfs_new_inode(dir, &dentry->d_name, mode); |
| 199 | 199 | if (!inode) |
| 200 | − return -ENOSPC; | |
| 200 | + return -ENOMEM; | |
| 201 | 201 | |
| 202 | 202 | res = hfs_cat_create(inode->i_ino, dir, &dentry->d_name, inode); |
| 203 | 203 | if (res) { |
| @@ -226,7 +226,7 @@ static int hfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) · 22 unmodified lines | ||
| 226 | 226 | |
| 227 | 227 | inode = hfs_new_inode(dir, &dentry->d_name, S_IFDIR | mode); |
| 228 | 228 | if (!inode) |
| 229 | − return -ENOSPC; | |
| 229 | + return -ENOMEM; | |
| 230 | 230 | |
| 231 | 231 | res = hfs_cat_create(inode->i_ino, dir, &dentry->d_name, inode); |
| 232 | 232 | if (res) { |
| @@ -118,9 +118,7 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd, · 117 unmodified lines | ||
| 118 | 118 | int b, e; |
| 119 | 119 | int res; |
| 120 | 120 | |
| 121 | − if (!rec_found) | |
| 122 | − BUG(); | |
| 123 | − | |
| 121 | + BUG_ON(!rec_found); | |
| 124 | 122 | b = 0; |
| 125 | 123 | e = bnode->num_recs - 1; |
| 126 | 124 | res = -ENOENT; |
| @@ -350,10 +350,11 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) · 349 unmodified lines | ||
| 350 | 350 | &fd.search_key->cat.name.unicode, |
| 351 | 351 | off + 2, len); |
| 352 | 352 | fd.search_key->key_len = cpu_to_be16(6 + len); |
| 353 | − } else | |
| 353 | + } else { | |
| 354 | 354 | err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); |
| 355 | 355 | if (unlikely(err)) |
| 356 | 356 | goto out; |
| 357 | + } | |
| 357 | 358 | |
| 358 | 359 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
| 359 | 360 | if (err) |
| @@ -434,7 +434,7 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, · 433 unmodified lines | ||
| 434 | 434 | { |
| 435 | 435 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); |
| 436 | 436 | struct inode *inode; |
| 437 | − int res = -ENOSPC; | |
| 437 | + int res = -ENOMEM; | |
| 438 | 438 | |
| 439 | 439 | mutex_lock(&sbi->vh_mutex); |
| 440 | 440 | inode = hfsplus_new_inode(dir->i_sb, S_IFLNK | S_IRWXUGO); |
| @@ -476,7 +476,7 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, · 35 unmodified lines | ||
| 476 | 476 | { |
| 477 | 477 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); |
| 478 | 478 | struct inode *inode; |
| 479 | − int res = -ENOSPC; | |
| 479 | + int res = -ENOMEM; | |
| 480 | 480 | |
| 481 | 481 | mutex_lock(&sbi->vh_mutex); |
| 482 | 482 | inode = hfsplus_new_inode(dir->i_sb, mode); |
| @@ -253,6 +253,12 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) · 252 unmodified lines | ||
| 253 | 253 | if ((attr->ia_valid & ATTR_SIZE) && |
| 254 | 254 | attr->ia_size != i_size_read(inode)) { |
| 255 | 255 | inode_dio_wait(inode); |
| 256 | + if (attr->ia_size > inode->i_size) { | |
| 257 | + error = generic_cont_expand_simple(inode, | |
| 258 | + attr->ia_size); | |
| 259 | + if (error) | |
| 260 | + return error; | |
| 261 | + } | |
| 256 | 262 | truncate_setsize(inode, attr->ia_size); |
| 257 | 263 | hfsplus_file_truncate(inode); |
| 258 | 264 | } |
| @@ -76,7 +76,7 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) · 75 unmodified lines | ||
| 76 | 76 | { |
| 77 | 77 | struct inode *inode = file_inode(file); |
| 78 | 78 | struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
| 79 | − unsigned int flags; | |
| 79 | + unsigned int flags, new_fl = 0; | |
| 80 | 80 | int err = 0; |
| 81 | 81 | |
| 82 | 82 | err = mnt_want_write_file(file); |
| @@ -110,14 +110,12 @@ static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) · 27 unmodified lines | ||
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | if (flags & FS_IMMUTABLE_FL) |
| 113 | − inode->i_flags |= S_IMMUTABLE; | |
| 114 | − else | |
| 115 | − inode->i_flags &= ~S_IMMUTABLE; | |
| 113 | + new_fl |= S_IMMUTABLE; | |
| 116 | 114 | |
| 117 | 115 | if (flags & FS_APPEND_FL) |
| 118 | − inode->i_flags |= S_APPEND; | |
| 119 | − else | |
| 120 | − inode->i_flags &= ~S_APPEND; | |
| 116 | + new_fl |= S_APPEND; | |
| 117 | + | |
| 118 | + inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); | |
| 121 | 119 | |
| 122 | 120 | if (flags & FS_NODUMP_FL) |
| 123 | 121 | hip->userflags |= HFSPLUS_FLG_NODUMP; |
| @@ -44,7 +44,7 @@ static int strcmp_xattr_acl(const char *name) · 43 unmodified lines | ||
| 44 | 44 | return -1; |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | −static inline int is_known_namespace(const char *name) | |
| 47 | +static bool is_known_namespace(const char *name) | |
| 48 | 48 | { |
| 49 | 49 | if (strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) && |
| 50 | 50 | strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && |
| @@ -424,6 +424,28 @@ static int copy_name(char *buffer, const char *xattr_name, int name_len) · 373 unmodified lines | ||
| 424 | 424 | return len; |
| 425 | 425 | } |
| 426 | 426 | |
| 427 | +int hfsplus_setxattr(struct dentry *dentry, const char *name, | |
| 428 | + const void *value, size_t size, int flags, | |
| 429 | + const char *prefix, size_t prefixlen) | |
| 430 | +{ | |
| 431 | + char *xattr_name; | |
| 432 | + int res; | |
| 433 | + | |
| 434 | + if (!strcmp(name, "")) | |
| 435 | + return -EINVAL; | |
| 436 | + | |
| 437 | + xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | |
| 438 | + GFP_KERNEL); | |
| 439 | + if (!xattr_name) | |
| 440 | + return -ENOMEM; | |
| 441 | + strcpy(xattr_name, prefix); | |
| 442 | + strcpy(xattr_name + prefixlen, name); | |
| 443 | + res = __hfsplus_setxattr(dentry->d_inode, xattr_name, value, size, | |
| 444 | + flags); | |
| 445 | + kfree(xattr_name); | |
| 446 | + return res; | |
| 447 | +} | |
| 448 | + | |
| 427 | 449 | static ssize_t hfsplus_getxattr_finder_info(struct inode *inode, |
| 428 | 450 | void *value, size_t size) |
| 429 | 451 | { |
| @@ -560,6 +582,30 @@ failed_getxattr_init: · 130 unmodified lines | ||
| 560 | 582 | return res; |
| 561 | 583 | } |
| 562 | 584 | |
| 585 | +ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | |
| 586 | + void *value, size_t size, | |
| 587 | + const char *prefix, size_t prefixlen) | |
| 588 | +{ | |
| 589 | + int res; | |
| 590 | + char *xattr_name; | |
| 591 | + | |
| 592 | + if (!strcmp(name, "")) | |
| 593 | + return -EINVAL; | |
| 594 | + | |
| 595 | + xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | |
| 596 | + GFP_KERNEL); | |
| 597 | + if (!xattr_name) | |
| 598 | + return -ENOMEM; | |
| 599 | + | |
| 600 | + strcpy(xattr_name, prefix); | |
| 601 | + strcpy(xattr_name + prefixlen, name); | |
| 602 | + | |
| 603 | + res = __hfsplus_getxattr(dentry->d_inode, xattr_name, value, size); | |
| 604 | + kfree(xattr_name); | |
| 605 | + return res; | |
| 606 | + | |
| 607 | +} | |
| 608 | + | |
| 563 | 609 | static inline int can_list(const char *xattr_name) |
| 564 | 610 | { |
| 565 | 611 | if (!xattr_name) |
| @@ -806,9 +852,6 @@ end_removexattr: · 240 unmodified lines | ||
| 806 | 852 | static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name, |
| 807 | 853 | void *buffer, size_t size, int type) |
| 808 | 854 | { |
| 809 | − char *xattr_name; | |
| 810 | − int res; | |
| 811 | − | |
| 812 | 855 | if (!strcmp(name, "")) |
| 813 | 856 | return -EINVAL; |
| 814 | 857 | |
| @@ -818,24 +861,19 @@ static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name, · 3 unmodified lines | ||
| 818 | 861 | */ |
| 819 | 862 | if (is_known_namespace(name)) |
| 820 | 863 | return -EOPNOTSUPP; |
| 821 | − xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN | |
| 822 | − + XATTR_MAC_OSX_PREFIX_LEN + 1, GFP_KERNEL); | |
| 823 | − if (!xattr_name) | |
| 824 | − return -ENOMEM; | |
| 825 | − strcpy(xattr_name, XATTR_MAC_OSX_PREFIX); | |
| 826 | − strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name); | |
| 827 | 864 | |
| 828 | − res = hfsplus_getxattr(dentry, xattr_name, buffer, size); | |
| 829 | − kfree(xattr_name); | |
| 830 | − return res; | |
| 865 | + /* | |
| 866 | + * osx is the namespace we use to indicate an unprefixed | |
| 867 | + * attribute on the filesystem (like the ones that OS X | |
| 868 | + * creates), so we pass the name through unmodified (after | |
| 869 | + * ensuring it doesn't conflict with another namespace). | |
| 870 | + */ | |
| 871 | + return __hfsplus_getxattr(dentry->d_inode, name, buffer, size); | |
| 831 | 872 | } |
| 832 | 873 | |
| 833 | 874 | static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name, |
| 834 | 875 | const void *buffer, size_t size, int flags, int type) |
| 835 | 876 | { |
| 836 | − char *xattr_name; | |
| 837 | − int res; | |
| 838 | − | |
| 839 | 877 | if (!strcmp(name, "")) |
| 840 | 878 | return -EINVAL; |
| 841 | 879 | |
| @@ -845,16 +883,14 @@ static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name, · 3 unmodified lines | ||
| 845 | 883 | */ |
| 846 | 884 | if (is_known_namespace(name)) |
| 847 | 885 | return -EOPNOTSUPP; |
| 848 | − xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN | |
| 849 | − + XATTR_MAC_OSX_PREFIX_LEN + 1, GFP_KERNEL); | |
| 850 | − if (!xattr_name) | |
| 851 | − return -ENOMEM; | |
| 852 | − strcpy(xattr_name, XATTR_MAC_OSX_PREFIX); | |
| 853 | − strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name); | |
| 854 | 886 | |
| 855 | − res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); | |
| 856 | − kfree(xattr_name); | |
| 857 | − return res; | |
| 887 | + /* | |
| 888 | + * osx is the namespace we use to indicate an unprefixed | |
| 889 | + * attribute on the filesystem (like the ones that OS X | |
| 890 | + * creates), so we pass the name through unmodified (after | |
| 891 | + * ensuring it doesn't conflict with another namespace). | |
| 892 | + */ | |
| 893 | + return __hfsplus_setxattr(dentry->d_inode, name, buffer, size, flags); | |
| 858 | 894 | } |
| 859 | 895 | |
| 860 | 896 | static size_t hfsplus_osx_listxattr(struct dentry *dentry, char *list, |
| @@ -21,22 +21,16 @@ extern const struct xattr_handler *hfsplus_xattr_handlers[]; · 20 unmodified lines | ||
| 21 | 21 | int __hfsplus_setxattr(struct inode *inode, const char *name, |
| 22 | 22 | const void *value, size_t size, int flags); |
| 23 | 23 | |
| 24 | −static inline int hfsplus_setxattr(struct dentry *dentry, const char *name, | |
| 25 | − const void *value, size_t size, int flags) | |
| 26 | −{ | |
| 27 | − return __hfsplus_setxattr(dentry->d_inode, name, value, size, flags); | |
| 28 | −} | |
| 24 | +int hfsplus_setxattr(struct dentry *dentry, const char *name, | |
| 25 | + const void *value, size_t size, int flags, | |
| 26 | + const char *prefix, size_t prefixlen); | |
| 29 | 27 | |
| 30 | 28 | ssize_t __hfsplus_getxattr(struct inode *inode, const char *name, |
| 31 | − void *value, size_t size); | |
| 32 | − | |
| 33 | −static inline ssize_t hfsplus_getxattr(struct dentry *dentry, | |
| 34 | − const char *name, | |
| 35 | − void *value, | |
| 36 | − size_t size) | |
| 37 | −{ | |
| 38 | − return __hfsplus_getxattr(dentry->d_inode, name, value, size); | |
| 39 | −} | |
| 29 | + void *value, size_t size); | |
| 30 | + | |
| 31 | +ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | |
| 32 | + void *value, size_t size, | |
| 33 | + const char *prefix, size_t prefixlen); | |
| 40 | 34 | |
| 41 | 35 | ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size); |
| 42 | 36 | |
| @@ -16,43 +16,17 @@ · 15 unmodified lines | ||
| 16 | 16 | static int hfsplus_security_getxattr(struct dentry *dentry, const char *name, |
| 17 | 17 | void *buffer, size_t size, int type) |
| 18 | 18 | { |
| 19 | − char *xattr_name; | |
| 20 | − int res; | |
| 21 | − | |
| 22 | − if (!strcmp(name, "")) | |
| 23 | − return -EINVAL; | |
| 24 | − | |
| 25 | − xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | |
| 26 | − GFP_KERNEL); | |
| 27 | − if (!xattr_name) | |
| 28 | − return -ENOMEM; | |
| 29 | − strcpy(xattr_name, XATTR_SECURITY_PREFIX); | |
| 30 | − strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name); | |
| 31 | − | |
| 32 | − res = hfsplus_getxattr(dentry, xattr_name, buffer, size); | |
| 33 | − kfree(xattr_name); | |
| 34 | − return res; | |
| 19 | + return hfsplus_getxattr(dentry, name, buffer, size, | |
| 20 | + XATTR_SECURITY_PREFIX, | |
| 21 | + XATTR_SECURITY_PREFIX_LEN); | |
| 35 | 22 | } |
| 36 | 23 | |
| 37 | 24 | static int hfsplus_security_setxattr(struct dentry *dentry, const char *name, |
| 38 | 25 | const void *buffer, size_t size, int flags, int type) |
| 39 | 26 | { |
| 40 | − char *xattr_name; | |
| 41 | − int res; | |
| 42 | − | |
| 43 | − if (!strcmp(name, "")) | |
| 44 | − return -EINVAL; | |
| 45 | − | |
| 46 | − xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | |
| 47 | − GFP_KERNEL); | |
| 48 | − if (!xattr_name) | |
| 49 | − return -ENOMEM; | |
| 50 | − strcpy(xattr_name, XATTR_SECURITY_PREFIX); | |
| 51 | − strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name); | |
| 52 | − | |
| 53 | − res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); | |
| 54 | − kfree(xattr_name); | |
| 55 | − return res; | |
| 27 | + return hfsplus_setxattr(dentry, name, buffer, size, flags, | |
| 28 | + XATTR_SECURITY_PREFIX, | |
| 29 | + XATTR_SECURITY_PREFIX_LEN); | |
| 56 | 30 | } |
| 57 | 31 | |
| 58 | 32 | static size_t hfsplus_security_listxattr(struct dentry *dentry, char *list, |
| @@ -14,43 +14,16 @@ · 13 unmodified lines | ||
| 14 | 14 | static int hfsplus_trusted_getxattr(struct dentry *dentry, const char *name, |
| 15 | 15 | void *buffer, size_t size, int type) |
| 16 | 16 | { |
| 17 | − char *xattr_name; | |
| 18 | − int res; | |
| 19 | − | |
| 20 | − if (!strcmp(name, "")) | |
| 21 | − return -EINVAL; | |
| 22 | − | |
| 23 | − xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | |
| 24 | − GFP_KERNEL); | |
| 25 | − if (!xattr_name) | |
| 26 | − return -ENOMEM; | |
| 27 | − strcpy(xattr_name, XATTR_TRUSTED_PREFIX); | |
| 28 | − strcpy(xattr_name + XATTR_TRUSTED_PREFIX_LEN, name); | |
| 29 | − | |
| 30 | − res = hfsplus_getxattr(dentry, xattr_name, buffer, size); | |
| 31 | − kfree(xattr_name); | |
| 32 | − return res; | |
| 17 | + return hfsplus_getxattr(dentry, name, buffer, size, | |
| 18 | + XATTR_TRUSTED_PREFIX, | |
| 19 | + XATTR_TRUSTED_PREFIX_LEN); | |
| 33 | 20 | } |
| 34 | 21 | |
| 35 | 22 | static int hfsplus_trusted_setxattr(struct dentry *dentry, const char *name, |
| 36 | 23 | const void *buffer, size_t size, int flags, int type) |
| 37 | 24 | { |
| 38 | − char *xattr_name; | |
| 39 | − int res; | |
| 40 | − | |
| 41 | − if (!strcmp(name, "")) | |
| 42 | − return -EINVAL; | |
| 43 | − | |
| 44 | − xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | |
| 45 | − GFP_KERNEL); | |
| 46 | − if (!xattr_name) | |
| 47 | − return -ENOMEM; | |
| 48 | − strcpy(xattr_name, XATTR_TRUSTED_PREFIX); | |
| 49 | − strcpy(xattr_name + XATTR_TRUSTED_PREFIX_LEN, name); | |
| 50 | − | |
| 51 | − res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); | |
| 52 | − kfree(xattr_name); | |
| 53 | − return res; | |
| 25 | + return hfsplus_setxattr(dentry, name, buffer, size, flags, | |
| 26 | + XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); | |
| 54 | 27 | } |
| 55 | 28 | |
| 56 | 29 | static size_t hfsplus_trusted_listxattr(struct dentry *dentry, char *list, |
| @@ -14,43 +14,16 @@ · 13 unmodified lines | ||
| 14 | 14 | static int hfsplus_user_getxattr(struct dentry *dentry, const char *name, |
| 15 | 15 | void *buffer, size_t size, int type) |
| 16 | 16 | { |
| 17 | − char *xattr_name; | |
| 18 | − int res; | |
| 19 | 17 | |
| 20 | − if (!strcmp(name, "")) | |
| 21 | − return -EINVAL; | |
| 22 | − | |
| 23 | − xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | |
| 24 | − GFP_KERNEL); | |
| 25 | − if (!xattr_name) | |
| 26 | − return -ENOMEM; | |
| 27 | − strcpy(xattr_name, XATTR_USER_PREFIX); | |
| 28 | − strcpy(xattr_name + XATTR_USER_PREFIX_LEN, name); | |
| 29 | − | |
| 30 | − res = hfsplus_getxattr(dentry, xattr_name, buffer, size); | |
| 31 | − kfree(xattr_name); | |
| 32 | − return res; | |
| 18 | + return hfsplus_getxattr(dentry, name, buffer, size, | |
| 19 | + XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); | |
| 33 | 20 | } |
| 34 | 21 | |
| 35 | 22 | static int hfsplus_user_setxattr(struct dentry *dentry, const char *name, |
| 36 | 23 | const void *buffer, size_t size, int flags, int type) |
| 37 | 24 | { |
| 38 | − char *xattr_name; | |
| 39 | − int res; | |
| 40 | − | |
| 41 | − if (!strcmp(name, "")) | |
| 42 | − return -EINVAL; | |
| 43 | − | |
| 44 | − xattr_name = kmalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN + 1, | |
| 45 | − GFP_KERNEL); | |
| 46 | − if (!xattr_name) | |
| 47 | − return -ENOMEM; | |
| 48 | − strcpy(xattr_name, XATTR_USER_PREFIX); | |
| 49 | − strcpy(xattr_name + XATTR_USER_PREFIX_LEN, name); | |
| 50 | − | |
| 51 | − res = hfsplus_setxattr(dentry, xattr_name, buffer, size, flags); | |
| 52 | − kfree(xattr_name); | |
| 53 | − return res; | |
| 25 | + return hfsplus_setxattr(dentry, name, buffer, size, flags, | |
| 26 | + XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); | |
| 54 | 27 | } |
| 55 | 28 | |
| 56 | 29 | static size_t hfsplus_user_listxattr(struct dentry *dentry, char *list, |
| @@ -2590,6 +2590,44 @@ static int locks_show(struct seq_file *f, void *v) · 2589 unmodified lines | ||
| 2590 | 2590 | return 0; |
| 2591 | 2591 | } |
| 2592 | 2592 | |
| 2593 | +static void __show_fd_locks(struct seq_file *f, | |
| 2594 | + struct list_head *head, int *id, | |
| 2595 | + struct file *filp, struct files_struct *files) | |
| 2596 | +{ | |
| 2597 | + struct file_lock *fl; | |
| 2598 | + | |
| 2599 | + list_for_each_entry(fl, head, fl_list) { | |
| 2600 | + | |
| 2601 | + if (filp != fl->fl_file) | |
| 2602 | + continue; | |
| 2603 | + if (fl->fl_owner != files && | |
| 2604 | + fl->fl_owner != filp) | |
| 2605 | + continue; | |
| 2606 | + | |
| 2607 | + (*id)++; | |
| 2608 | + seq_puts(f, "lock:\t"); | |
| 2609 | + lock_get_status(f, fl, *id, ""); | |
| 2610 | + } | |
| 2611 | +} | |
| 2612 | + | |
| 2613 | +void show_fd_locks(struct seq_file *f, | |
| 2614 | + struct file *filp, struct files_struct *files) | |
| 2615 | +{ | |
| 2616 | + struct inode *inode = file_inode(filp); | |
| 2617 | + struct file_lock_context *ctx; | |
| 2618 | + int id = 0; | |
| 2619 | + | |
| 2620 | + ctx = inode->i_flctx; | |
| 2621 | + if (!ctx) | |
| 2622 | + return; | |
| 2623 | + | |
| 2624 | + spin_lock(&ctx->flc_lock); | |
| 2625 | + __show_fd_locks(f, &ctx->flc_flock, &id, filp, files); | |
| 2626 | + __show_fd_locks(f, &ctx->flc_posix, &id, filp, files); | |
| 2627 | + __show_fd_locks(f, &ctx->flc_lease, &id, filp, files); | |
| 2628 | + spin_unlock(&ctx->flc_lock); | |
| 2629 | +} | |
| 2630 | + | |
| 2593 | 2631 | static void *locks_start(struct seq_file *f, loff_t *pos) |
| 2594 | 2632 | __acquires(&blocked_lock_lock) |
| 2595 | 2633 | { |
| @@ -405,13 +405,14 @@ nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode, · 404 unmodified lines | ||
| 405 | 405 | static int nilfs_palloc_count_desc_blocks(struct inode *inode, |
| 406 | 406 | unsigned long *desc_blocks) |
| 407 | 407 | { |
| 408 | − unsigned long blknum; | |
| 408 | + __u64 blknum; | |
| 409 | 409 | int ret; |
| 410 | 410 | |
| 411 | 411 | ret = nilfs_bmap_last_key(NILFS_I(inode)->i_bmap, &blknum); |
| 412 | 412 | if (likely(!ret)) |
| 413 | 413 | *desc_blocks = DIV_ROUND_UP( |
| 414 | − blknum, NILFS_MDT(inode)->mi_blocks_per_desc_block); | |
| 414 | + (unsigned long)blknum, | |
| 415 | + NILFS_MDT(inode)->mi_blocks_per_desc_block); | |
| 415 | 416 | return ret; |
| 416 | 417 | } |
| 417 | 418 | |
| @@ -152,9 +152,7 @@ static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) · 151 unmodified lines | ||
| 152 | 152 | * |
| 153 | 153 | * %-EEXIST - A record associated with @key already exist. |
| 154 | 154 | */ |
| 155 | −int nilfs_bmap_insert(struct nilfs_bmap *bmap, | |
| 156 | − unsigned long key, | |
| 157 | − unsigned long rec) | |
| 155 | +int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec) | |
| 158 | 156 | { |
| 159 | 157 | int ret; |
| 160 | 158 | |
| @@ -191,19 +189,47 @@ static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key) · 30 unmodified lines | ||
| 191 | 189 | return bmap->b_ops->bop_delete(bmap, key); |
| 192 | 190 | } |
| 193 | 191 | |
| 194 | −int nilfs_bmap_last_key(struct nilfs_bmap *bmap, unsigned long *key) | |
| 192 | +/** | |
| 193 | + * nilfs_bmap_seek_key - seek a valid entry and return its key | |
| 194 | + * @bmap: bmap struct | |
| 195 | + * @start: start key number | |
| 196 | + * @keyp: place to store valid key | |
| 197 | + * | |
| 198 | + * Description: nilfs_bmap_seek_key() seeks a valid key on @bmap | |
| 199 | + * starting from @start, and stores it to @keyp if found. | |
| 200 | + * | |
| 201 | + * Return Value: On success, 0 is returned. On error, one of the following | |
| 202 | + * negative error codes is returned. | |
| 203 | + * | |
| 204 | + * %-EIO - I/O error. | |
| 205 | + * | |
| 206 | + * %-ENOMEM - Insufficient amount of memory available. | |
| 207 | + * | |
| 208 | + * %-ENOENT - No valid entry was found | |
| 209 | + */ | |
| 210 | +int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp) | |
| 195 | 211 | { |
| 196 | − __u64 lastkey; | |
| 197 | 212 | int ret; |
| 198 | 213 | |
| 199 | 214 | down_read(&bmap->b_sem); |
| 200 | − ret = bmap->b_ops->bop_last_key(bmap, &lastkey); | |
| 215 | + ret = bmap->b_ops->bop_seek_key(bmap, start, keyp); | |
| 216 | + up_read(&bmap->b_sem); | |
| 217 | + | |
| 218 | + if (ret < 0) | |
| 219 | + ret = nilfs_bmap_convert_error(bmap, __func__, ret); | |
| 220 | + return ret; | |
| 221 | +} | |
| 222 | + | |
| 223 | +int nilfs_bmap_last_key(struct nilfs_bmap *bmap, __u64 *keyp) | |
| 224 | +{ | |
| 225 | + int ret; | |
| 226 | + | |
| 227 | + down_read(&bmap->b_sem); | |
| 228 | + ret = bmap->b_ops->bop_last_key(bmap, keyp); | |
| 201 | 229 | up_read(&bmap->b_sem); |
| 202 | 230 | |
| 203 | 231 | if (ret < 0) |
| 204 | 232 | ret = nilfs_bmap_convert_error(bmap, __func__, ret); |
| 205 | − else | |
| 206 | − *key = lastkey; | |
| 207 | 233 | return ret; |
| 208 | 234 | } |
| 209 | 235 | |
| @@ -224,7 +250,7 @@ int nilfs_bmap_last_key(struct nilfs_bmap *bmap, unsigned long *key) · 14 unmodified lines | ||
| 224 | 250 | * |
| 225 | 251 | * %-ENOENT - A record associated with @key does not exist. |
| 226 | 252 | */ |
| 227 | −int nilfs_bmap_delete(struct nilfs_bmap *bmap, unsigned long key) | |
| 253 | +int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key) | |
| 228 | 254 | { |
| 229 | 255 | int ret; |
| 230 | 256 | |
| @@ -235,7 +261,7 @@ int nilfs_bmap_delete(struct nilfs_bmap *bmap, unsigned long key) · 4 unmodified lines | ||
| 235 | 261 | return nilfs_bmap_convert_error(bmap, __func__, ret); |
| 236 | 262 | } |
| 237 | 263 | |
| 238 | −static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key) | |
| 264 | +static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, __u64 key) | |
| 239 | 265 | { |
| 240 | 266 | __u64 lastkey; |
| 241 | 267 | int ret; |
| @@ -276,7 +302,7 @@ static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key) · 34 unmodified lines | ||
| 276 | 302 | * |
| 277 | 303 | * %-ENOMEM - Insufficient amount of memory available. |
| 278 | 304 | */ |
| 279 | −int nilfs_bmap_truncate(struct nilfs_bmap *bmap, unsigned long key) | |
| 305 | +int nilfs_bmap_truncate(struct nilfs_bmap *bmap, __u64 key) | |
| 280 | 306 | { |
| 281 | 307 | int ret; |
| 282 | 308 | |
| @@ -76,8 +76,10 @@ struct nilfs_bmap_operations { · 75 unmodified lines | ||
| 76 | 76 | union nilfs_binfo *); |
| 77 | 77 | int (*bop_mark)(struct nilfs_bmap *, __u64, int); |
| 78 | 78 | |
| 79 | − /* The following functions are internal use only. */ | |
| 79 | + int (*bop_seek_key)(const struct nilfs_bmap *, __u64, __u64 *); | |
| 80 | 80 | int (*bop_last_key)(const struct nilfs_bmap *, __u64 *); |
| 81 | + | |
| 82 | + /* The following functions are internal use only. */ | |
| 81 | 83 | int (*bop_check_insert)(const struct nilfs_bmap *, __u64); |
| 82 | 84 | int (*bop_check_delete)(struct nilfs_bmap *, __u64); |
| 83 | 85 | int (*bop_gather_data)(struct nilfs_bmap *, __u64 *, __u64 *, int); |
| @@ -153,10 +155,11 @@ int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *); · 69 unmodified lines | ||
| 153 | 155 | int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); |
| 154 | 156 | void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); |
| 155 | 157 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned); |
| 156 | −int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long); | |
| 157 | −int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long); | |
| 158 | −int nilfs_bmap_last_key(struct nilfs_bmap *, unsigned long *); | |
| 159 | −int nilfs_bmap_truncate(struct nilfs_bmap *, unsigned long); | |
| 158 | +int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec); | |
| 159 | +int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key); | |
| 160 | +int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp); | |
| 161 | +int nilfs_bmap_last_key(struct nilfs_bmap *bmap, __u64 *keyp); | |
| 162 | +int nilfs_bmap_truncate(struct nilfs_bmap *bmap, __u64 key); | |
| 160 | 163 | void nilfs_bmap_clear(struct nilfs_bmap *); |
| 161 | 164 | int nilfs_bmap_propagate(struct nilfs_bmap *, struct buffer_head *); |
| 162 | 165 | void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *, struct list_head *); |
| @@ -633,6 +633,44 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_bmap *btree, · 632 unmodified lines | ||
| 633 | 633 | return 0; |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | +/** | |
| 637 | + * nilfs_btree_get_next_key - get next valid key from btree path array | |
| 638 | + * @btree: bmap struct of btree | |
| 639 | + * @path: array of nilfs_btree_path struct | |
| 640 | + * @minlevel: start level | |
| 641 | + * @nextkey: place to store the next valid key | |
| 642 | + * | |
| 643 | + * Return Value: If a next key was found, 0 is returned. Otherwise, | |
| 644 | + * -ENOENT is returned. | |
| 645 | + */ | |
| 646 | +static int nilfs_btree_get_next_key(const struct nilfs_bmap *btree, | |
| 647 | + const struct nilfs_btree_path *path, | |
| 648 | + int minlevel, __u64 *nextkey) | |
| 649 | +{ | |
| 650 | + struct nilfs_btree_node *node; | |
| 651 | + int maxlevel = nilfs_btree_height(btree) - 1; | |
| 652 | + int index, next_adj, level; | |
| 653 | + | |
| 654 | + /* Next index is already set to bp_index for leaf nodes. */ | |
| 655 | + next_adj = 0; | |
| 656 | + for (level = minlevel; level <= maxlevel; level++) { | |
| 657 | + if (level == maxlevel) | |
| 658 | + node = nilfs_btree_get_root(btree); | |
| 659 | + else | |
| 660 | + node = nilfs_btree_get_nonroot_node(path, level); | |
| 661 | + | |
| 662 | + index = path[level].bp_index + next_adj; | |
| 663 | + if (index < nilfs_btree_node_get_nchildren(node)) { | |
| 664 | + /* Next key is in this node */ | |
| 665 | + *nextkey = nilfs_btree_node_get_key(node, index); | |
| 666 | + return 0; | |
| 667 | + } | |
| 668 | + /* For non-leaf nodes, next index is stored at bp_index + 1. */ | |
| 669 | + next_adj = 1; | |
| 670 | + } | |
| 671 | + return -ENOENT; | |
| 672 | +} | |
| 673 | + | |
| 636 | 674 | static int nilfs_btree_lookup(const struct nilfs_bmap *btree, |
| 637 | 675 | __u64 key, int level, __u64 *ptrp) |
| 638 | 676 | { |
| @@ -1563,6 +1601,27 @@ out: · 924 unmodified lines | ||
| 1563 | 1601 | return ret; |
| 1564 | 1602 | } |
| 1565 | 1603 | |
| 1604 | +static int nilfs_btree_seek_key(const struct nilfs_bmap *btree, __u64 start, | |
| 1605 | + __u64 *keyp) | |
| 1606 | +{ | |
| 1607 | + struct nilfs_btree_path *path; | |
| 1608 | + const int minlevel = NILFS_BTREE_LEVEL_NODE_MIN; | |
| 1609 | + int ret; | |
| 1610 | + | |
| 1611 | + path = nilfs_btree_alloc_path(); | |
| 1612 | + if (!path) | |
| 1613 | + return -ENOMEM; | |
| 1614 | + | |
| 1615 | + ret = nilfs_btree_do_lookup(btree, path, start, NULL, minlevel, 0); | |
| 1616 | + if (!ret) | |
| 1617 | + *keyp = start; | |
| 1618 | + else if (ret == -ENOENT) | |
| 1619 | + ret = nilfs_btree_get_next_key(btree, path, minlevel, keyp); | |
| 1620 | + | |
| 1621 | + nilfs_btree_free_path(path); | |
| 1622 | + return ret; | |
| 1623 | +} | |
| 1624 | + | |
| 1566 | 1625 | static int nilfs_btree_last_key(const struct nilfs_bmap *btree, __u64 *keyp) |
| 1567 | 1626 | { |
| 1568 | 1627 | struct nilfs_btree_path *path; |
| @@ -2298,7 +2357,9 @@ static const struct nilfs_bmap_operations nilfs_btree_ops = { · 729 unmodified lines | ||
| 2298 | 2357 | .bop_assign = nilfs_btree_assign, |
| 2299 | 2358 | .bop_mark = nilfs_btree_mark, |
| 2300 | 2359 | |
| 2360 | + .bop_seek_key = nilfs_btree_seek_key, | |
| 2301 | 2361 | .bop_last_key = nilfs_btree_last_key, |
| 2362 | + | |
| 2302 | 2363 | .bop_check_insert = NULL, |
| 2303 | 2364 | .bop_check_delete = nilfs_btree_check_delete, |
| 2304 | 2365 | .bop_gather_data = nilfs_btree_gather_data, |
| @@ -2318,7 +2379,9 @@ static const struct nilfs_bmap_operations nilfs_btree_ops_gc = { · 13 unmodified lines | ||
| 2318 | 2379 | .bop_assign = nilfs_btree_assign_gc, |
| 2319 | 2380 | .bop_mark = NULL, |
| 2320 | 2381 | |
| 2382 | + .bop_seek_key = NULL, | |
| 2321 | 2383 | .bop_last_key = NULL, |
| 2384 | + | |
| 2322 | 2385 | .bop_check_insert = NULL, |
| 2323 | 2386 | .bop_check_delete = NULL, |
| 2324 | 2387 | .bop_gather_data = NULL, |
| @@ -53,6 +53,13 @@ nilfs_cpfile_get_offset(const struct inode *cpfile, __u64 cno) · 52 unmodified lines | ||
| 53 | 53 | return do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | +static __u64 nilfs_cpfile_first_checkpoint_in_block(const struct inode *cpfile, | |
| 57 | + unsigned long blkoff) | |
| 58 | +{ | |
| 59 | + return (__u64)nilfs_cpfile_checkpoints_per_block(cpfile) * blkoff | |
| 60 | + + 1 - NILFS_MDT(cpfile)->mi_first_entry_offset; | |
| 61 | +} | |
| 62 | + | |
| 56 | 63 | static unsigned long |
| 57 | 64 | nilfs_cpfile_checkpoints_in_block(const struct inode *cpfile, |
| 58 | 65 | __u64 curr, |
| @@ -146,6 +153,44 @@ static inline int nilfs_cpfile_get_checkpoint_block(struct inode *cpfile, · 87 unmodified lines | ||
| 146 | 153 | create, nilfs_cpfile_block_init, bhp); |
| 147 | 154 | } |
| 148 | 155 | |
| 156 | +/** | |
| 157 | + * nilfs_cpfile_find_checkpoint_block - find and get a buffer on cpfile | |
| 158 | + * @cpfile: inode of cpfile | |
| 159 | + * @start_cno: start checkpoint number (inclusive) | |
| 160 | + * @end_cno: end checkpoint number (inclusive) | |
| 161 | + * @cnop: place to store the next checkpoint number | |
| 162 | + * @bhp: place to store a pointer to buffer_head struct | |
| 163 | + * | |
| 164 | + * Return Value: On success, it returns 0. On error, the following negative | |
| 165 | + * error code is returned. | |
| 166 | + * | |
| 167 | + * %-ENOMEM - Insufficient memory available. | |
| 168 | + * | |
| 169 | + * %-EIO - I/O error | |
| 170 | + * | |
| 171 | + * %-ENOENT - no block exists in the range. | |
| 172 | + */ | |
| 173 | +static int nilfs_cpfile_find_checkpoint_block(struct inode *cpfile, | |
| 174 | + __u64 start_cno, __u64 end_cno, | |
| 175 | + __u64 *cnop, | |
| 176 | + struct buffer_head **bhp) | |
| 177 | +{ | |
| 178 | + unsigned long start, end, blkoff; | |
| 179 | + int ret; | |
| 180 | + | |
| 181 | + if (unlikely(start_cno > end_cno)) | |
| 182 | + return -ENOENT; | |
| 183 | + | |
| 184 | + start = nilfs_cpfile_get_blkoff(cpfile, start_cno); | |
| 185 | + end = nilfs_cpfile_get_blkoff(cpfile, end_cno); | |
| 186 | + | |
| 187 | + ret = nilfs_mdt_find_block(cpfile, start, end, &blkoff, bhp); | |
| 188 | + if (!ret) | |
| 189 | + *cnop = (blkoff == start) ? start_cno : | |
| 190 | + nilfs_cpfile_first_checkpoint_in_block(cpfile, blkoff); | |
| 191 | + return ret; | |
| 192 | +} | |
| 193 | + | |
| 149 | 194 | static inline int nilfs_cpfile_delete_checkpoint_block(struct inode *cpfile, |
| 150 | 195 | __u64 cno) |
| 151 | 196 | { |
| @@ -403,14 +448,15 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, · 251 unmodified lines | ||
| 403 | 448 | return -ENOENT; /* checkpoint number 0 is invalid */ |
| 404 | 449 | down_read(&NILFS_MDT(cpfile)->mi_sem); |
| 405 | 450 | |
| 406 | − for (n = 0; cno < cur_cno && n < nci; cno += ncps) { | |
| 407 | − ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, cur_cno); | |
| 408 | − ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh); | |
| 451 | + for (n = 0; n < nci; cno += ncps) { | |
| 452 | + ret = nilfs_cpfile_find_checkpoint_block( | |
| 453 | + cpfile, cno, cur_cno - 1, &cno, &bh); | |
| 409 | 454 | if (ret < 0) { |
| 410 | − if (ret != -ENOENT) | |
| 411 | − goto out; | |
| 412 | − continue; /* skip hole */ | |
| 455 | + if (likely(ret == -ENOENT)) | |
| 456 | + break; | |
| 457 | + goto out; | |
| 413 | 458 | } |
| 459 | + ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, cur_cno); | |
| 414 | 460 | |
| 415 | 461 | kaddr = kmap_atomic(bh->b_page); |
| 416 | 462 | cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); |
| @@ -173,6 +173,21 @@ static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key) · 172 unmodified lines | ||
| 173 | 173 | return ret; |
| 174 | 174 | } |
| 175 | 175 | |
| 176 | +static int nilfs_direct_seek_key(const struct nilfs_bmap *direct, __u64 start, | |
| 177 | + __u64 *keyp) | |
| 178 | +{ | |
| 179 | + __u64 key; | |
| 180 | + | |
| 181 | + for (key = start; key <= NILFS_DIRECT_KEY_MAX; key++) { | |
| 182 | + if (nilfs_direct_get_ptr(direct, key) != | |
| 183 | + NILFS_BMAP_INVALID_PTR) { | |
| 184 | + *keyp = key; | |
| 185 | + return 0; | |
| 186 | + } | |
| 187 | + } | |
| 188 | + return -ENOENT; | |
| 189 | +} | |
| 190 | + | |
| 176 | 191 | static int nilfs_direct_last_key(const struct nilfs_bmap *direct, __u64 *keyp) |
| 177 | 192 | { |
| 178 | 193 | __u64 key, lastkey; |
| @@ -355,7 +370,9 @@ static const struct nilfs_bmap_operations nilfs_direct_ops = { · 176 unmodified lines | ||
| 355 | 370 | .bop_assign = nilfs_direct_assign, |
| 356 | 371 | .bop_mark = NULL, |
| 357 | 372 | |
| 373 | + .bop_seek_key = nilfs_direct_seek_key, | |
| 358 | 374 | .bop_last_key = nilfs_direct_last_key, |
| 375 | + | |
| 359 | 376 | .bop_check_insert = nilfs_direct_check_insert, |
| 360 | 377 | .bop_check_delete = NULL, |
| 361 | 378 | .bop_gather_data = nilfs_direct_gather_data, |
| @@ -106,7 +106,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, · 105 unmodified lines | ||
| 106 | 106 | err = nilfs_transaction_begin(inode->i_sb, &ti, 1); |
| 107 | 107 | if (unlikely(err)) |
| 108 | 108 | goto out; |
| 109 | − err = nilfs_bmap_insert(ii->i_bmap, (unsigned long)blkoff, | |
| 109 | + err = nilfs_bmap_insert(ii->i_bmap, blkoff, | |
| 110 | 110 | (unsigned long)bh_result); |
| 111 | 111 | if (unlikely(err != 0)) { |
| 112 | 112 | if (err == -EEXIST) { |
| @@ -441,21 +441,20 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode) · 328 unmodified lines | ||
| 441 | 441 | void nilfs_set_inode_flags(struct inode *inode) |
| 442 | 442 | { |
| 443 | 443 | unsigned int flags = NILFS_I(inode)->i_flags; |
| 444 | + unsigned int new_fl = 0; | |
| 444 | 445 | |
| 445 | − inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | | |
| 446 | − S_DIRSYNC); | |
| 447 | 446 | if (flags & FS_SYNC_FL) |
| 448 | − inode->i_flags |= S_SYNC; | |
| 447 | + new_fl |= S_SYNC; | |
| 449 | 448 | if (flags & FS_APPEND_FL) |
| 450 | − inode->i_flags |= S_APPEND; | |
| 449 | + new_fl |= S_APPEND; | |
| 451 | 450 | if (flags & FS_IMMUTABLE_FL) |
| 452 | − inode->i_flags |= S_IMMUTABLE; | |
| 451 | + new_fl |= S_IMMUTABLE; | |
| 453 | 452 | if (flags & FS_NOATIME_FL) |
| 454 | − inode->i_flags |= S_NOATIME; | |
| 453 | + new_fl |= S_NOATIME; | |
| 455 | 454 | if (flags & FS_DIRSYNC_FL) |
| 456 | − inode->i_flags |= S_DIRSYNC; | |
| 457 | − mapping_set_gfp_mask(inode->i_mapping, | |
| 458 | − mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | |
| 455 | + new_fl |= S_DIRSYNC; | |
| 456 | + inode_set_flags(inode, new_fl, S_SYNC | S_APPEND | S_IMMUTABLE | | |
| 457 | + S_NOATIME | S_DIRSYNC); | |
| 459 | 458 | } |
| 460 | 459 | |
| 461 | 460 | int nilfs_read_inode_common(struct inode *inode, |
| @@ -540,6 +539,8 @@ static int __nilfs_read_inode(struct super_block *sb, · 78 unmodified lines | ||
| 540 | 539 | brelse(bh); |
| 541 | 540 | up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
| 542 | 541 | nilfs_set_inode_flags(inode); |
| 542 | + mapping_set_gfp_mask(inode->i_mapping, | |
| 543 | + mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | |
| 543 | 544 | return 0; |
| 544 | 545 | |
| 545 | 546 | failed_unmap: |
| @@ -712,7 +713,7 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh, int flags) · 166 unmodified lines | ||
| 712 | 713 | static void nilfs_truncate_bmap(struct nilfs_inode_info *ii, |
| 713 | 714 | unsigned long from) |
| 714 | 715 | { |
| 715 | − unsigned long b; | |
| 716 | + __u64 b; | |
| 716 | 717 | int ret; |
| 717 | 718 | |
| 718 | 719 | if (!test_bit(NILFS_I_BMAP, &ii->i_state)) |
| @@ -727,7 +728,7 @@ repeat: · 8 unmodified lines | ||
| 727 | 728 | if (b < from) |
| 728 | 729 | return; |
| 729 | 730 | |
| 730 | − b -= min_t(unsigned long, NILFS_MAX_TRUNCATE_BLOCKS, b - from); | |
| 731 | + b -= min_t(__u64, NILFS_MAX_TRUNCATE_BLOCKS, b - from); | |
| 731 | 732 | ret = nilfs_bmap_truncate(ii->i_bmap, b); |
| 732 | 733 | nilfs_relax_pressure_in_lock(ii->vfs_inode.i_sb); |
| 733 | 734 | if (!ret || (ret == -ENOMEM && |
| @@ -260,6 +260,60 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, · 259 unmodified lines | ||
| 260 | 260 | return ret; |
| 261 | 261 | } |
| 262 | 262 | |
| 263 | +/** | |
| 264 | + * nilfs_mdt_find_block - find and get a buffer on meta data file. | |
| 265 | + * @inode: inode of the meta data file | |
| 266 | + * @start: start block offset (inclusive) | |
| 267 | + * @end: end block offset (inclusive) | |
| 268 | + * @blkoff: block offset | |
| 269 | + * @out_bh: place to store a pointer to buffer_head struct | |
| 270 | + * | |
| 271 | + * nilfs_mdt_find_block() looks up an existing block in range of | |
| 272 | + * [@start, @end] and stores pointer to a buffer head of the block to | |
| 273 | + * @out_bh, and block offset to @blkoff, respectively. @out_bh and | |
| 274 | + * @blkoff are substituted only when zero is returned. | |
| 275 | + * | |
| 276 | + * Return Value: On success, it returns 0. On error, the following negative | |
| 277 | + * error code is returned. | |
| 278 | + * | |
| 279 | + * %-ENOMEM - Insufficient memory available. | |
| 280 | + * | |
| 281 | + * %-EIO - I/O error | |
| 282 | + * | |
| 283 | + * %-ENOENT - no block was found in the range | |
| 284 | + */ | |
| 285 | +int nilfs_mdt_find_block(struct inode *inode, unsigned long start, | |
| 286 | + unsigned long end, unsigned long *blkoff, | |
| 287 | + struct buffer_head **out_bh) | |
| 288 | +{ | |
| 289 | + __u64 next; | |
| 290 | + int ret; | |
| 291 | + | |
| 292 | + if (unlikely(start > end)) | |
| 293 | + return -ENOENT; | |
| 294 | + | |
| 295 | + ret = nilfs_mdt_read_block(inode, start, true, out_bh); | |
| 296 | + if (!ret) { | |
| 297 | + *blkoff = start; | |
| 298 | + goto out; | |
| 299 | + } | |
| 300 | + if (unlikely(ret != -ENOENT || start == ULONG_MAX)) | |
| 301 | + goto out; | |
| 302 | + | |
| 303 | + ret = nilfs_bmap_seek_key(NILFS_I(inode)->i_bmap, start + 1, &next); | |
| 304 | + if (!ret) { | |
| 305 | + if (next <= end) { | |
| 306 | + ret = nilfs_mdt_read_block(inode, next, true, out_bh); | |
| 307 | + if (!ret) | |
| 308 | + *blkoff = next; | |
| 309 | + } else { | |
| 310 | + ret = -ENOENT; | |
| 311 | + } | |
| 312 | + } | |
| 313 | +out: | |
| 314 | + return ret; | |
| 315 | +} | |
| 316 | + | |
| 263 | 317 | /** |
| 264 | 318 | * nilfs_mdt_delete_block - make a hole on the meta data file. |
| 265 | 319 | * @inode: inode of the meta data file |
| @@ -78,6 +78,9 @@ int nilfs_mdt_get_block(struct inode *, unsigned long, int, · 77 unmodified lines | ||
| 78 | 78 | void (*init_block)(struct inode *, |
| 79 | 79 | struct buffer_head *, void *), |
| 80 | 80 | struct buffer_head **); |
| 81 | +int nilfs_mdt_find_block(struct inode *inode, unsigned long start, | |
| 82 | + unsigned long end, unsigned long *blkoff, | |
| 83 | + struct buffer_head **out_bh); | |
| 81 | 84 | int nilfs_mdt_delete_block(struct inode *, unsigned long); |
| 82 | 85 | int nilfs_mdt_forget_block(struct inode *, unsigned long); |
| 83 | 86 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); |
| @@ -111,7 +114,10 @@ static inline __u64 nilfs_mdt_cno(struct inode *inode) · 27 unmodified lines | ||
| 111 | 114 | return ((struct the_nilfs *)inode->i_sb->s_fs_info)->ns_cno; |
| 112 | 115 | } |
| 113 | 116 | |
| 114 | −#define nilfs_mdt_bgl_lock(inode, bg) \ | |
| 115 | − (&NILFS_MDT(inode)->mi_bgl->locks[(bg) & (NR_BG_LOCKS-1)].lock) | |
| 117 | +static inline spinlock_t * | |
| 118 | +nilfs_mdt_bgl_lock(struct inode *inode, unsigned int block_group) | |
| 119 | +{ | |
| 120 | + return bgl_lock_ptr(NILFS_MDT(inode)->mi_bgl, block_group); | |
| 121 | +} | |
| 116 | 122 | |
| 117 | 123 | #endif /* _NILFS_MDT_H */ |
| @@ -89,18 +89,16 @@ struct buffer_head *nilfs_grab_buffer(struct inode *inode, · 88 unmodified lines | ||
| 89 | 89 | void nilfs_forget_buffer(struct buffer_head *bh) |
| 90 | 90 | { |
| 91 | 91 | struct page *page = bh->b_page; |
| 92 | + const unsigned long clear_bits = | |
| 93 | + (1 << BH_Uptodate | 1 << BH_Dirty | 1 << BH_Mapped | | |
| 94 | + 1 << BH_Async_Write | 1 << BH_NILFS_Volatile | | |
| 95 | + 1 << BH_NILFS_Checked | 1 << BH_NILFS_Redirected); | |
| 92 | 96 | |
| 93 | 97 | lock_buffer(bh); |
| 94 | − clear_buffer_nilfs_volatile(bh); | |
| 95 | − clear_buffer_nilfs_checked(bh); | |
| 96 | − clear_buffer_nilfs_redirected(bh); | |
| 97 | − clear_buffer_async_write(bh); | |
| 98 | − clear_buffer_dirty(bh); | |
| 98 | + set_mask_bits(&bh->b_state, clear_bits, 0); | |
| 99 | 99 | if (nilfs_page_buffers_clean(page)) |
| 100 | 100 | __nilfs_clear_page_dirty(page); |
| 101 | 101 | |
| 102 | − clear_buffer_uptodate(bh); | |
| 103 | − clear_buffer_mapped(bh); | |
| 104 | 102 | bh->b_blocknr = -1; |
| 105 | 103 | ClearPageUptodate(page); |
| 106 | 104 | ClearPageMappedToDisk(page); |
| @@ -421,6 +419,10 @@ void nilfs_clear_dirty_page(struct page *page, bool silent) · 314 unmodified lines | ||
| 421 | 419 | |
| 422 | 420 | if (page_has_buffers(page)) { |
| 423 | 421 | struct buffer_head *bh, *head; |
| 422 | + const unsigned long clear_bits = | |
| 423 | + (1 << BH_Uptodate | 1 << BH_Dirty | 1 << BH_Mapped | | |
| 424 | + 1 << BH_Async_Write | 1 << BH_NILFS_Volatile | | |
| 425 | + 1 << BH_NILFS_Checked | 1 << BH_NILFS_Redirected); | |
| 424 | 426 | |
| 425 | 427 | bh = head = page_buffers(page); |
| 426 | 428 | do { |
| @@ -430,13 +432,7 @@ void nilfs_clear_dirty_page(struct page *page, bool silent) · 3 unmodified lines | ||
| 430 | 432 | "discard block %llu, size %zu", |
| 431 | 433 | (u64)bh->b_blocknr, bh->b_size); |
| 432 | 434 | } |
| 433 | − clear_buffer_async_write(bh); | |
| 434 | − clear_buffer_dirty(bh); | |
| 435 | − clear_buffer_nilfs_volatile(bh); | |
| 436 | − clear_buffer_nilfs_checked(bh); | |
| 437 | − clear_buffer_nilfs_redirected(bh); | |
| 438 | − clear_buffer_uptodate(bh); | |
| 439 | − clear_buffer_mapped(bh); | |
| 435 | + set_mask_bits(&bh->b_state, clear_bits, 0); | |
| 440 | 436 | unlock_buffer(bh); |
| 441 | 437 | } while (bh = bh->b_this_page, bh != head); |
| 442 | 438 | } |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <linux/pagemap.h> |
| 25 | 25 | #include <linux/buffer_head.h> |
| 26 | 26 | #include <linux/writeback.h> |
| 27 | +#include <linux/bitops.h> | |
| 27 | 28 | #include <linux/bio.h> |
| 28 | 29 | #include <linux/completion.h> |
| 29 | 30 | #include <linux/blkdev.h> |
| @@ -1588,7 +1589,6 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) · 1558 unmodified lines | ||
| 1588 | 1589 | |
| 1589 | 1590 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, |
| 1590 | 1591 | b_assoc_buffers) { |
| 1591 | − set_buffer_async_write(bh); | |
| 1592 | 1592 | if (bh->b_page != bd_page) { |
| 1593 | 1593 | if (bd_page) { |
| 1594 | 1594 | lock_page(bd_page); |
| @@ -1688,7 +1688,6 @@ static void nilfs_abort_logs(struct list_head *logs, int err) · 93 unmodified lines | ||
| 1688 | 1688 | list_for_each_entry(segbuf, logs, sb_list) { |
| 1689 | 1689 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, |
| 1690 | 1690 | b_assoc_buffers) { |
| 1691 | − clear_buffer_async_write(bh); | |
| 1692 | 1691 | if (bh->b_page != bd_page) { |
| 1693 | 1692 | if (bd_page) |
| 1694 | 1693 | end_page_writeback(bd_page); |
| @@ -1768,7 +1767,6 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) · 73 unmodified lines | ||
| 1768 | 1767 | b_assoc_buffers) { |
| 1769 | 1768 | set_buffer_uptodate(bh); |
| 1770 | 1769 | clear_buffer_dirty(bh); |
| 1771 | − clear_buffer_async_write(bh); | |
| 1772 | 1770 | if (bh->b_page != bd_page) { |
| 1773 | 1771 | if (bd_page) |
| 1774 | 1772 | end_page_writeback(bd_page); |
| @@ -1788,12 +1786,13 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) · 13 unmodified lines | ||
| 1788 | 1786 | */ |
| 1789 | 1787 | list_for_each_entry(bh, &segbuf->sb_payload_buffers, |
| 1790 | 1788 | b_assoc_buffers) { |
| 1791 | − set_buffer_uptodate(bh); | |
| 1792 | − clear_buffer_dirty(bh); | |
| 1793 | − clear_buffer_async_write(bh); | |
| 1794 | − clear_buffer_delay(bh); | |
| 1795 | − clear_buffer_nilfs_volatile(bh); | |
| 1796 | − clear_buffer_nilfs_redirected(bh); | |
| 1789 | + const unsigned long set_bits = (1 << BH_Uptodate); | |
| 1790 | + const unsigned long clear_bits = | |
| 1791 | + (1 << BH_Dirty | 1 << BH_Async_Write | | |
| 1792 | + 1 << BH_Delay | 1 << BH_NILFS_Volatile | | |
| 1793 | + 1 << BH_NILFS_Redirected); | |
| 1794 | + | |
| 1795 | + set_mask_bits(&bh->b_state, clear_bits, set_bits); | |
| 1797 | 1796 | if (bh == segbuf->sb_super_root) { |
| 1798 | 1797 | if (bh->b_page != bd_page) { |
| 1799 | 1798 | end_page_writeback(bd_page); |
| @@ -1020,7 +1020,7 @@ int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno) · 1019 unmodified lines | ||
| 1020 | 1020 | struct dentry *dentry; |
| 1021 | 1021 | int ret; |
| 1022 | 1022 | |
| 1023 | − if (cno < 0 || cno > nilfs->ns_cno) | |
| 1023 | + if (cno > nilfs->ns_cno) | |
| 1024 | 1024 | return false; |
| 1025 | 1025 | |
| 1026 | 1026 | if (cno >= nilfs_last_cno(nilfs)) |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/security.h> |
| 9 | 9 | #include <linux/file.h> |
| 10 | 10 | #include <linux/seq_file.h> |
| 11 | +#include <linux/fs.h> | |
| 11 | 12 | |
| 12 | 13 | #include <linux/proc_fs.h> |
| 13 | 14 | |
| @@ -48,17 +49,23 @@ static int seq_show(struct seq_file *m, void *v) · 34 unmodified lines | ||
| 48 | 49 | put_files_struct(files); |
| 49 | 50 | } |
| 50 | 51 | |
| 51 | − if (!ret) { | |
| 52 | − seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n", | |
| 53 | − (long long)file->f_pos, f_flags, | |
| 54 | − real_mount(file->f_path.mnt)->mnt_id); | |
| 55 | − if (file->f_op->show_fdinfo) | |
| 56 | − file->f_op->show_fdinfo(m, file); | |
| 57 | − ret = seq_has_overflowed(m); | |
| 58 | − fput(file); | |
| 59 | − } | |
| 52 | + if (ret) | |
| 53 | + return ret; | |
| 60 | 54 | |
| 61 | − return ret; | |
| 55 | + seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n", | |
| 56 | + (long long)file->f_pos, f_flags, | |
| 57 | + real_mount(file->f_path.mnt)->mnt_id); | |
| 58 | + | |
| 59 | + show_fd_locks(m, file, files); | |
| 60 | + if (seq_has_overflowed(m)) | |
| 61 | + goto out; | |
| 62 | + | |
| 63 | + if (file->f_op->show_fdinfo) | |
| 64 | + file->f_op->show_fdinfo(m, file); | |
| 65 | + | |
| 66 | +out: | |
| 67 | + fput(file); | |
| 68 | + return 0; | |
| 62 | 69 | } |
| 63 | 70 | |
| 64 | 71 | static int seq_fdinfo_open(struct inode *inode, struct file *file) |
| @@ -17,7 +17,9 @@ · 16 unmodified lines | ||
| 17 | 17 | #define __NR_seccomp_read_32 __NR_read |
| 18 | 18 | #define __NR_seccomp_write_32 __NR_write |
| 19 | 19 | #define __NR_seccomp_exit_32 __NR_exit |
| 20 | +#ifndef __NR_seccomp_sigreturn_32 | |
| 20 | 21 | #define __NR_seccomp_sigreturn_32 __NR_rt_sigreturn |
| 22 | +#endif | |
| 21 | 23 | #endif /* CONFIG_COMPAT && ! already defined */ |
| 22 | 24 | |
| 23 | 25 | #define __NR_seccomp_read __NR_read |
| @@ -283,16 +283,16 @@ static inline int bitmap_empty(const unsigned long *src, unsigned nbits) · 282 unmodified lines | ||
| 283 | 283 | { |
| 284 | 284 | if (small_const_nbits(nbits)) |
| 285 | 285 | return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); |
| 286 | − else | |
| 287 | − return __bitmap_empty(src, nbits); | |
| 286 | + | |
| 287 | + return find_first_bit(src, nbits) == nbits; | |
| 288 | 288 | } |
| 289 | 289 | |
| 290 | 290 | static inline int bitmap_full(const unsigned long *src, unsigned int nbits) |
| 291 | 291 | { |
| 292 | 292 | if (small_const_nbits(nbits)) |
| 293 | 293 | return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); |
| 294 | − else | |
| 295 | − return __bitmap_full(src, nbits); | |
| 294 | + | |
| 295 | + return find_first_zero_bit(src, nbits) == nbits; | |
| 296 | 296 | } |
| 297 | 297 | |
| 298 | 298 | static inline int bitmap_weight(const unsigned long *src, unsigned int nbits) |
| @@ -218,9 +218,9 @@ static inline unsigned long __ffs64(u64 word) · 217 unmodified lines | ||
| 218 | 218 | /** |
| 219 | 219 | * find_last_bit - find the last set bit in a memory region |
| 220 | 220 | * @addr: The address to start the search at |
| 221 | − * @size: The maximum size to search | |
| 221 | + * @size: The number of bits to search | |
| 222 | 222 | * |
| 223 | − * Returns the bit number of the first set bit, or size. | |
| 223 | + * Returns the bit number of the last set bit, or size. | |
| 224 | 224 | */ |
| 225 | 225 | extern unsigned long find_last_bit(const unsigned long *addr, |
| 226 | 226 | unsigned long size); |
| @@ -875,6 +875,7 @@ static inline struct file *get_file(struct file *f) · 874 unmodified lines | ||
| 875 | 875 | atomic_long_inc(&f->f_count); |
| 876 | 876 | return f; |
| 877 | 877 | } |
| 878 | +#define get_file_rcu(x) atomic_long_inc_not_zero(&(x)->f_count) | |
| 878 | 879 | #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1) |
| 879 | 880 | #define file_count(x) atomic_long_read(&(x)->f_count) |
| 880 | 881 | |
| @@ -1046,6 +1047,9 @@ extern void lease_get_mtime(struct inode *, struct timespec *time); · 165 unmodified lines | ||
| 1046 | 1047 | extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); |
| 1047 | 1048 | extern int vfs_setlease(struct file *, long, struct file_lock **, void **); |
| 1048 | 1049 | extern int lease_modify(struct file_lock *, int, struct list_head *); |
| 1050 | +struct files_struct; | |
| 1051 | +extern void show_fd_locks(struct seq_file *f, | |
| 1052 | + struct file *filp, struct files_struct *files); | |
| 1049 | 1053 | #else /* !CONFIG_FILE_LOCKING */ |
| 1050 | 1054 | static inline int fcntl_getlk(struct file *file, unsigned int cmd, |
| 1051 | 1055 | struct flock __user *user) |
| @@ -1182,6 +1186,10 @@ static inline int lease_modify(struct file_lock *fl, int arg, · 130 unmodified lines | ||
| 1182 | 1186 | { |
| 1183 | 1187 | return -EINVAL; |
| 1184 | 1188 | } |
| 1189 | + | |
| 1190 | +struct files_struct; | |
| 1191 | +static inline void show_fd_locks(struct seq_file *f, | |
| 1192 | + struct file *filp, struct files_struct *files) {} | |
| 1185 | 1193 | #endif /* !CONFIG_FILE_LOCKING */ |
| 1186 | 1194 | |
| 1187 | 1195 | |
| @@ -22,14 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | #define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) |
| 23 | 23 | #define ___config_enabled(__ignored, val, ...) val |
| 24 | 24 | |
| 25 | −/* | |
| 26 | − * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', | |
| 27 | − * 0 otherwise. | |
| 28 | − * | |
| 29 | − */ | |
| 30 | −#define IS_ENABLED(option) \ | |
| 31 | − (config_enabled(option) || config_enabled(option##_MODULE)) | |
| 32 | − | |
| 33 | 25 | /* |
| 34 | 26 | * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 |
| 35 | 27 | * otherwise. For boolean options, this is equivalent to |
| @@ -43,4 +35,11 @@ · 7 unmodified lines | ||
| 43 | 35 | */ |
| 44 | 36 | #define IS_MODULE(option) config_enabled(option##_MODULE) |
| 45 | 37 | |
| 38 | +/* | |
| 39 | + * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', | |
| 40 | + * 0 otherwise. | |
| 41 | + */ | |
| 42 | +#define IS_ENABLED(option) \ | |
| 43 | + (IS_BUILTIN(option) || IS_MODULE(option)) | |
| 44 | + | |
| 46 | 45 | #endif /* __LINUX_KCONFIG_H */ |
| @@ -103,6 +103,18 @@ · 102 unmodified lines | ||
| 103 | 103 | (((__x) - ((__d) / 2)) / (__d)); \ |
| 104 | 104 | } \ |
| 105 | 105 | ) |
| 106 | +/* | |
| 107 | + * Same as above but for u64 dividends. divisor must be a 32-bit | |
| 108 | + * number. | |
| 109 | + */ | |
| 110 | +#define DIV_ROUND_CLOSEST_ULL(x, divisor)( \ | |
| 111 | +{ \ | |
| 112 | + typeof(divisor) __d = divisor; \ | |
| 113 | + unsigned long long _tmp = (x) + (__d) / 2; \ | |
| 114 | + do_div(_tmp, __d); \ | |
| 115 | + _tmp; \ | |
| 116 | +} \ | |
| 117 | +) | |
| 106 | 118 | |
| 107 | 119 | /* |
| 108 | 120 | * Multiplies an integer by a fraction, while avoiding unnecessary |
| @@ -105,6 +105,8 @@ enum s2mps_rtc_reg { · 104 unmodified lines | ||
| 105 | 105 | #define S5M_RTC_UDR_MASK (1 << S5M_RTC_UDR_SHIFT) |
| 106 | 106 | #define S2MPS_RTC_WUDR_SHIFT 4 |
| 107 | 107 | #define S2MPS_RTC_WUDR_MASK (1 << S2MPS_RTC_WUDR_SHIFT) |
| 108 | +#define S2MPS13_RTC_AUDR_SHIFT 1 | |
| 109 | +#define S2MPS13_RTC_AUDR_MASK (1 << S2MPS13_RTC_AUDR_SHIFT) | |
| 108 | 110 | #define S2MPS_RTC_RUDR_SHIFT 0 |
| 109 | 111 | #define S2MPS_RTC_RUDR_MASK (1 << S2MPS_RTC_RUDR_SHIFT) |
| 110 | 112 | #define RTC_TCON_SHIFT 1 |
| @@ -429,7 +429,7 @@ struct mm_struct { · 428 unmodified lines | ||
| 429 | 429 | #endif |
| 430 | 430 | |
| 431 | 431 | /* store ref to file /proc/<pid>/exe symlink points to */ |
| 432 | − struct file *exe_file; | |
| 432 | + struct file __rcu *exe_file; | |
| 433 | 433 | #ifdef CONFIG_MMU_NOTIFIER |
| 434 | 434 | struct mmu_notifier_mm *mmu_notifier_mm; |
| 435 | 435 | #endif |
| @@ -212,4 +212,7 @@ static inline void setup_sysctl_set(struct ctl_table_set *p, · 211 unmodified lines | ||
| 212 | 212 | |
| 213 | 213 | #endif /* CONFIG_SYSCTL */ |
| 214 | 214 | |
| 215 | +int sysctl_max_threads(struct ctl_table *table, int write, | |
| 216 | + void __user *buffer, size_t *lenp, loff_t *ppos); | |
| 217 | + | |
| 215 | 218 | #endif /* _LINUX_SYSCTL_H */ |
| @@ -0,0 +1,40 @@ | ||
| 1 | +#ifndef _LINUX_HELPER_MACROS_H_ | |
| 2 | +#define _LINUX_HELPER_MACROS_H_ | |
| 3 | + | |
| 4 | +#define __find_closest(x, a, as, op) \ | |
| 5 | +({ \ | |
| 6 | + typeof(as) __fc_i, __fc_as = (as) - 1; \ | |
| 7 | + typeof(x) __fc_x = (x); \ | |
| 8 | + typeof(*a) *__fc_a = (a); \ | |
| 9 | + for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ | |
| 10 | + if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \ | |
| 11 | + __fc_a[__fc_i + 1], 2)) \ | |
| 12 | + break; \ | |
| 13 | + } \ | |
| 14 | + (__fc_i); \ | |
| 15 | +}) | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * find_closest - locate the closest element in a sorted array | |
| 19 | + * @x: The reference value. | |
| 20 | + * @a: The array in which to look for the closest element. Must be sorted | |
| 21 | + * in ascending order. | |
| 22 | + * @as: Size of 'a'. | |
| 23 | + * | |
| 24 | + * Returns the index of the element closest to 'x'. | |
| 25 | + */ | |
| 26 | +#define find_closest(x, a, as) __find_closest(x, a, as, <=) | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * find_closest_descending - locate the closest element in a sorted array | |
| 30 | + * @x: The reference value. | |
| 31 | + * @a: The array in which to look for the closest element. Must be sorted | |
| 32 | + * in descending order. | |
| 33 | + * @as: Size of 'a'. | |
| 34 | + * | |
| 35 | + * Similar to find_closest() but 'a' is expected to be sorted in descending | |
| 36 | + * order. | |
| 37 | + */ | |
| 38 | +#define find_closest_descending(x, a, as) __find_closest(x, a, as, >=) | |
| 39 | + | |
| 40 | +#endif | |
| @@ -6,7 +6,16 @@ · 5 unmodified lines | ||
| 6 | 6 | #define EDEADLK 35 /* Resource deadlock would occur */ |
| 7 | 7 | #define ENAMETOOLONG 36 /* File name too long */ |
| 8 | 8 | #define ENOLCK 37 /* No record locks available */ |
| 9 | −#define ENOSYS 38 /* Function not implemented */ | |
| 9 | + | |
| 10 | +/* | |
| 11 | + * This error code is special: arch syscall entry code will return | |
| 12 | + * -ENOSYS if users try to call a syscall that doesn't exist. To keep | |
| 13 | + * failures of syscalls that really do exist distinguishable from | |
| 14 | + * failures due to attempts to use a nonexistent syscall, syscall | |
| 15 | + * implementations should refrain from returning -ENOSYS. | |
| 16 | + */ | |
| 17 | +#define ENOSYS 38 /* Invalid system call number */ | |
| 18 | + | |
| 10 | 19 | #define ENOTEMPTY 39 /* Directory not empty */ |
| 11 | 20 | #define ELOOP 40 /* Too many symbolic links encountered */ |
| 12 | 21 | #define EWOULDBLOCK EAGAIN /* Operation would block */ |
| @@ -91,7 +91,7 @@ · 90 unmodified lines | ||
| 91 | 91 | static int kernel_init(void *); |
| 92 | 92 | |
| 93 | 93 | extern void init_IRQ(void); |
| 94 | −extern void fork_init(unsigned long); | |
| 94 | +extern void fork_init(void); | |
| 95 | 95 | extern void radix_tree_init(void); |
| 96 | 96 | #ifndef CONFIG_DEBUG_RODATA |
| 97 | 97 | static inline void mark_rodata_ro(void) { } |
| @@ -645,7 +645,7 @@ asmlinkage __visible void __init start_kernel(void) · 547 unmodified lines | ||
| 645 | 645 | #endif |
| 646 | 646 | thread_info_cache_init(); |
| 647 | 647 | cred_init(); |
| 648 | − fork_init(totalram_pages); | |
| 648 | + fork_init(); | |
| 649 | 649 | proc_caches_init(); |
| 650 | 650 | buffer_init(); |
| 651 | 651 | key_init(); |
| @@ -74,6 +74,7 @@ · 73 unmodified lines | ||
| 74 | 74 | #include <linux/uprobes.h> |
| 75 | 75 | #include <linux/aio.h> |
| 76 | 76 | #include <linux/compiler.h> |
| 77 | +#include <linux/sysctl.h> | |
| 77 | 78 | |
| 78 | 79 | #include <asm/pgtable.h> |
| 79 | 80 | #include <asm/pgalloc.h> |
| @@ -87,6 +88,16 @@ · 7 unmodified lines | ||
| 87 | 88 | #define CREATE_TRACE_POINTS |
| 88 | 89 | #include <trace/events/task.h> |
| 89 | 90 | |
| 91 | +/* | |
| 92 | + * Minimum number of threads to boot the kernel | |
| 93 | + */ | |
| 94 | +#define MIN_THREADS 20 | |
| 95 | + | |
| 96 | +/* | |
| 97 | + * Maximum number of threads | |
| 98 | + */ | |
| 99 | +#define MAX_THREADS FUTEX_TID_MASK | |
| 100 | + | |
| 90 | 101 | /* |
| 91 | 102 | * Protected counters by write_lock_irq(&tasklist_lock) |
| 92 | 103 | */ |
| @@ -253,7 +264,30 @@ EXPORT_SYMBOL_GPL(__put_task_struct); · 160 unmodified lines | ||
| 253 | 264 | |
| 254 | 265 | void __init __weak arch_task_cache_init(void) { } |
| 255 | 266 | |
| 256 | −void __init fork_init(unsigned long mempages) | |
| 267 | +/* | |
| 268 | + * set_max_threads | |
| 269 | + */ | |
| 270 | +static void set_max_threads(unsigned int max_threads_suggested) | |
| 271 | +{ | |
| 272 | + u64 threads; | |
| 273 | + | |
| 274 | + /* | |
| 275 | + * The number of threads shall be limited such that the thread | |
| 276 | + * structures may only consume a small part of the available memory. | |
| 277 | + */ | |
| 278 | + if (fls64(totalram_pages) + fls64(PAGE_SIZE) > 64) | |
| 279 | + threads = MAX_THREADS; | |
| 280 | + else | |
| 281 | + threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE, | |
| 282 | + (u64) THREAD_SIZE * 8UL); | |
| 283 | + | |
| 284 | + if (threads > max_threads_suggested) | |
| 285 | + threads = max_threads_suggested; | |
| 286 | + | |
| 287 | + max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS); | |
| 288 | +} | |
| 289 | + | |
| 290 | +void __init fork_init(void) | |
| 257 | 291 | { |
| 258 | 292 | #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR |
| 259 | 293 | #ifndef ARCH_MIN_TASKALIGN |
| @@ -268,18 +302,7 @@ void __init fork_init(unsigned long mempages) · 8 unmodified lines | ||
| 268 | 302 | /* do the arch specific task caches init */ |
| 269 | 303 | arch_task_cache_init(); |
| 270 | 304 | |
| 271 | − /* | |
| 272 | − * The default maximum number of threads is set to a safe | |
| 273 | − * value: the thread structures can take up at most half | |
| 274 | − * of memory. | |
| 275 | − */ | |
| 276 | − max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE); | |
| 277 | − | |
| 278 | − /* | |
| 279 | − * we need to allow at least 20 threads to boot a system | |
| 280 | − */ | |
| 281 | − if (max_threads < 20) | |
| 282 | − max_threads = 20; | |
| 305 | + set_max_threads(MAX_THREADS); | |
| 283 | 306 | |
| 284 | 307 | init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; |
| 285 | 308 | init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; |
| @@ -380,6 +403,9 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) · 94 unmodified lines | ||
| 380 | 403 | */ |
| 381 | 404 | down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING); |
| 382 | 405 | |
| 406 | + /* No ordering required: file already has been exposed. */ | |
| 407 | + RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); | |
| 408 | + | |
| 383 | 409 | mm->total_vm = oldmm->total_vm; |
| 384 | 410 | mm->shared_vm = oldmm->shared_vm; |
| 385 | 411 | mm->exec_vm = oldmm->exec_vm; |
| @@ -505,7 +531,13 @@ static inline void mm_free_pgd(struct mm_struct *mm) · 119 unmodified lines | ||
| 505 | 531 | pgd_free(mm, mm->pgd); |
| 506 | 532 | } |
| 507 | 533 | #else |
| 508 | −#define dup_mmap(mm, oldmm) (0) | |
| 534 | +static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |
| 535 | +{ | |
| 536 | + down_write(&oldmm->mmap_sem); | |
| 537 | + RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); | |
| 538 | + up_write(&oldmm->mmap_sem); | |
| 539 | + return 0; | |
| 540 | +} | |
| 509 | 541 | #define mm_alloc_pgd(mm) (0) |
| 510 | 542 | #define mm_free_pgd(mm) |
| 511 | 543 | #endif /* CONFIG_MMU */ |
| @@ -674,34 +706,53 @@ void mmput(struct mm_struct *mm) · 162 unmodified lines | ||
| 674 | 706 | } |
| 675 | 707 | EXPORT_SYMBOL_GPL(mmput); |
| 676 | 708 | |
| 709 | +/** | |
| 710 | + * set_mm_exe_file - change a reference to the mm's executable file | |
| 711 | + * | |
| 712 | + * This changes mm's executable file (shown as symlink /proc/[pid]/exe). | |
| 713 | + * | |
| 714 | + * Main users are mmput() and sys_execve(). Callers prevent concurrent | |
| 715 | + * invocations: in mmput() nobody alive left, in execve task is single | |
| 716 | + * threaded. sys_prctl(PR_SET_MM_MAP/EXE_FILE) also needs to set the | |
| 717 | + * mm->exe_file, but does so without using set_mm_exe_file() in order | |
| 718 | + * to do avoid the need for any locks. | |
| 719 | + */ | |
| 677 | 720 | void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file) |
| 678 | 721 | { |
| 722 | + struct file *old_exe_file; | |
| 723 | + | |
| 724 | + /* | |
| 725 | + * It is safe to dereference the exe_file without RCU as | |
| 726 | + * this function is only called if nobody else can access | |
| 727 | + * this mm -- see comment above for justification. | |
| 728 | + */ | |
| 729 | + old_exe_file = rcu_dereference_raw(mm->exe_file); | |
| 730 | + | |
| 679 | 731 | if (new_exe_file) |
| 680 | 732 | get_file(new_exe_file); |
| 681 | − if (mm->exe_file) | |
| 682 | − fput(mm->exe_file); | |
| 683 | − mm->exe_file = new_exe_file; | |
| 733 | + rcu_assign_pointer(mm->exe_file, new_exe_file); | |
| 734 | + if (old_exe_file) | |
| 735 | + fput(old_exe_file); | |
| 684 | 736 | } |
| 685 | 737 | |
| 738 | +/** | |
| 739 | + * get_mm_exe_file - acquire a reference to the mm's executable file | |
| 740 | + * | |
| 741 | + * Returns %NULL if mm has no associated executable file. | |
| 742 | + * User must release file via fput(). | |
| 743 | + */ | |
| 686 | 744 | struct file *get_mm_exe_file(struct mm_struct *mm) |
| 687 | 745 | { |
| 688 | 746 | struct file *exe_file; |
| 689 | 747 | |
| 690 | − /* We need mmap_sem to protect against races with removal of exe_file */ | |
| 691 | − down_read(&mm->mmap_sem); | |
| 692 | − exe_file = mm->exe_file; | |
| 693 | − if (exe_file) | |
| 694 | − get_file(exe_file); | |
| 695 | − up_read(&mm->mmap_sem); | |
| 748 | + rcu_read_lock(); | |
| 749 | + exe_file = rcu_dereference(mm->exe_file); | |
| 750 | + if (exe_file && !get_file_rcu(exe_file)) | |
| 751 | + exe_file = NULL; | |
| 752 | + rcu_read_unlock(); | |
| 696 | 753 | return exe_file; |
| 697 | 754 | } |
| 698 | − | |
| 699 | −static void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm) | |
| 700 | −{ | |
| 701 | − /* It's safe to write the exe_file pointer without exe_file_lock because | |
| 702 | − * this is called during fork when the task is not yet in /proc */ | |
| 703 | − newmm->exe_file = get_mm_exe_file(oldmm); | |
| 704 | −} | |
| 755 | +EXPORT_SYMBOL(get_mm_exe_file); | |
| 705 | 756 | |
| 706 | 757 | /** |
| 707 | 758 | * get_task_mm - acquire a reference to the task's mm |
| @@ -864,8 +915,6 @@ static struct mm_struct *dup_mm(struct task_struct *tsk) · 156 unmodified lines | ||
| 864 | 915 | if (!mm_init(mm, tsk)) |
| 865 | 916 | goto fail_nomem; |
| 866 | 917 | |
| 867 | − dup_mm_exe_file(oldmm, mm); | |
| 868 | − | |
| 869 | 918 | err = dup_mmap(mm, oldmm); |
| 870 | 919 | if (err) |
| 871 | 920 | goto free_pt; |
| @@ -1403,10 +1452,11 @@ static struct task_struct *copy_process(unsigned long clone_flags, · 531 unmodified lines | ||
| 1403 | 1452 | goto bad_fork_cleanup_io; |
| 1404 | 1453 | |
| 1405 | 1454 | if (pid != &init_struct_pid) { |
| 1406 | − retval = -ENOMEM; | |
| 1407 | 1455 | pid = alloc_pid(p->nsproxy->pid_ns_for_children); |
| 1408 | − if (!pid) | |
| 1456 | + if (IS_ERR(pid)) { | |
| 1457 | + retval = PTR_ERR(pid); | |
| 1409 | 1458 | goto bad_fork_cleanup_io; |
| 1459 | + } | |
| 1410 | 1460 | } |
| 1411 | 1461 | |
| 1412 | 1462 | p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; |
| @@ -2000,3 +2050,26 @@ int unshare_files(struct files_struct **displaced) · 587 unmodified lines | ||
| 2000 | 2050 | task_unlock(task); |
| 2001 | 2051 | return 0; |
| 2002 | 2052 | } |
| 2053 | + | |
| 2054 | +int sysctl_max_threads(struct ctl_table *table, int write, | |
| 2055 | + void __user *buffer, size_t *lenp, loff_t *ppos) | |
| 2056 | +{ | |
| 2057 | + struct ctl_table t; | |
| 2058 | + int ret; | |
| 2059 | + int threads = max_threads; | |
| 2060 | + int min = MIN_THREADS; | |
| 2061 | + int max = MAX_THREADS; | |
| 2062 | + | |
| 2063 | + t = *table; | |
| 2064 | + t.data = &threads; | |
| 2065 | + t.extra1 = &min; | |
| 2066 | + t.extra2 = &max; | |
| 2067 | + | |
| 2068 | + ret = proc_dointvec_minmax(&t, write, buffer, lenp, ppos); | |
| 2069 | + if (ret || !write) | |
| 2070 | + return ret; | |
| 2071 | + | |
| 2072 | + set_max_threads(threads); | |
| 2073 | + | |
| 2074 | + return 0; | |
| 2075 | +} | |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/init.h> |
| 19 | 19 | #include <linux/module.h> |
| 20 | 20 | #include <linux/mutex.h> |
| 21 | +#include <linux/sched.h> | |
| 21 | 22 | #include "gcov.h" |
| 22 | 23 | |
| 23 | 24 | static int gcov_events_enabled; |
| @@ -107,8 +108,10 @@ void gcov_enable_events(void) · 83 unmodified lines | ||
| 107 | 108 | gcov_events_enabled = 1; |
| 108 | 109 | |
| 109 | 110 | /* Perform event callback for previously registered entries. */ |
| 110 | − while ((info = gcov_info_next(info))) | |
| 111 | + while ((info = gcov_info_next(info))) { | |
| 111 | 112 | gcov_event(GCOV_ADD, info); |
| 113 | + cond_resched(); | |
| 114 | + } | |
| 112 | 115 | |
| 113 | 116 | mutex_unlock(&gcov_lock); |
| 114 | 117 | } |
| @@ -182,7 +182,7 @@ static int alloc_pidmap(struct pid_namespace *pid_ns) · 181 unmodified lines | ||
| 182 | 182 | spin_unlock_irq(&pidmap_lock); |
| 183 | 183 | kfree(page); |
| 184 | 184 | if (unlikely(!map->page)) |
| 185 | − break; | |
| 185 | + return -ENOMEM; | |
| 186 | 186 | } |
| 187 | 187 | if (likely(atomic_read(&map->nr_free))) { |
| 188 | 188 | for ( ; ; ) { |
| @@ -210,7 +210,7 @@ static int alloc_pidmap(struct pid_namespace *pid_ns) · 21 unmodified lines | ||
| 210 | 210 | } |
| 211 | 211 | pid = mk_pid(pid_ns, map, offset); |
| 212 | 212 | } |
| 213 | − return -1; | |
| 213 | + return -EAGAIN; | |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | 216 | int next_pidmap(struct pid_namespace *pid_ns, unsigned int last) |
| @@ -301,17 +301,20 @@ struct pid *alloc_pid(struct pid_namespace *ns) · 84 unmodified lines | ||
| 301 | 301 | int i, nr; |
| 302 | 302 | struct pid_namespace *tmp; |
| 303 | 303 | struct upid *upid; |
| 304 | + int retval = -ENOMEM; | |
| 304 | 305 | |
| 305 | 306 | pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL); |
| 306 | 307 | if (!pid) |
| 307 | − goto out; | |
| 308 | + return ERR_PTR(retval); | |
| 308 | 309 | |
| 309 | 310 | tmp = ns; |
| 310 | 311 | pid->level = ns->level; |
| 311 | 312 | for (i = ns->level; i >= 0; i--) { |
| 312 | 313 | nr = alloc_pidmap(tmp); |
| 313 | − if (nr < 0) | |
| 314 | + if (IS_ERR_VALUE(nr)) { | |
| 315 | + retval = nr; | |
| 314 | 316 | goto out_free; |
| 317 | + } | |
| 315 | 318 | |
| 316 | 319 | pid->numbers[i].nr = nr; |
| 317 | 320 | pid->numbers[i].ns = tmp; |
| @@ -339,7 +342,6 @@ struct pid *alloc_pid(struct pid_namespace *ns) · 21 unmodified lines | ||
| 339 | 342 | } |
| 340 | 343 | spin_unlock_irq(&pidmap_lock); |
| 341 | 344 | |
| 342 | −out: | |
| 343 | 345 | return pid; |
| 344 | 346 | |
| 345 | 347 | out_unlock: |
| @@ -351,8 +353,7 @@ out_free: · 5 unmodified lines | ||
| 351 | 353 | free_pidmap(pid->numbers + i); |
| 352 | 354 | |
| 353 | 355 | kmem_cache_free(ns->pid_cachep, pid); |
| 354 | − pid = NULL; | |
| 355 | − goto out; | |
| 356 | + return ERR_PTR(retval); | |
| 356 | 357 | } |
| 357 | 358 | |
| 358 | 359 | void disable_pid_allocation(struct pid_namespace *ns) |
| @@ -456,8 +456,6 @@ static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) · 455 unmodified lines | ||
| 456 | 456 | |
| 457 | 457 | static int ptrace_detach(struct task_struct *child, unsigned int data) |
| 458 | 458 | { |
| 459 | − bool dead = false; | |
| 460 | − | |
| 461 | 459 | if (!valid_signal(data)) |
| 462 | 460 | return -EIO; |
| 463 | 461 | |
| @@ -467,18 +465,19 @@ static int ptrace_detach(struct task_struct *child, unsigned int data) · 3 unmodified lines | ||
| 467 | 465 | |
| 468 | 466 | write_lock_irq(&tasklist_lock); |
| 469 | 467 | /* |
| 470 | − * This child can be already killed. Make sure de_thread() or | |
| 471 | − * our sub-thread doing do_wait() didn't do release_task() yet. | |
| 468 | + * We rely on ptrace_freeze_traced(). It can't be killed and | |
| 469 | + * untraced by another thread, it can't be a zombie. | |
| 472 | 470 | */ |
| 473 | − if (child->ptrace) { | |
| 474 | − child->exit_code = data; | |
| 475 | − dead = __ptrace_detach(current, child); | |
| 476 | − } | |
| 471 | + WARN_ON(!child->ptrace || child->exit_state); | |
| 472 | + /* | |
| 473 | + * tasklist_lock avoids the race with wait_task_stopped(), see | |
| 474 | + * the comment in ptrace_resume(). | |
| 475 | + */ | |
| 476 | + child->exit_code = data; | |
| 477 | + __ptrace_detach(current, child); | |
| 477 | 478 | write_unlock_irq(&tasklist_lock); |
| 478 | 479 | |
| 479 | 480 | proc_ptrace_connector(child, PTRACE_DETACH); |
| 480 | − if (unlikely(dead)) | |
| 481 | − release_task(child); | |
| 482 | 481 | |
| 483 | 482 | return 0; |
| 484 | 483 | } |
| @@ -697,6 +696,8 @@ static int ptrace_peek_siginfo(struct task_struct *child, · 212 unmodified lines | ||
| 697 | 696 | static int ptrace_resume(struct task_struct *child, long request, |
| 698 | 697 | unsigned long data) |
| 699 | 698 | { |
| 699 | + bool need_siglock; | |
| 700 | + | |
| 700 | 701 | if (!valid_signal(data)) |
| 701 | 702 | return -EIO; |
| 702 | 703 | |
| @@ -724,8 +725,26 @@ static int ptrace_resume(struct task_struct *child, long request, · 21 unmodified lines | ||
| 724 | 725 | user_disable_single_step(child); |
| 725 | 726 | } |
| 726 | 727 | |
| 728 | + /* | |
| 729 | + * Change ->exit_code and ->state under siglock to avoid the race | |
| 730 | + * with wait_task_stopped() in between; a non-zero ->exit_code will | |
| 731 | + * wrongly look like another report from tracee. | |
| 732 | + * | |
| 733 | + * Note that we need siglock even if ->exit_code == data and/or this | |
| 734 | + * status was not reported yet, the new status must not be cleared by | |
| 735 | + * wait_task_stopped() after resume. | |
| 736 | + * | |
| 737 | + * If data == 0 we do not care if wait_task_stopped() reports the old | |
| 738 | + * status and clears the code too; this can't race with the tracee, it | |
| 739 | + * takes siglock after resume. | |
| 740 | + */ | |
| 741 | + need_siglock = data && !thread_group_empty(current); | |
| 742 | + if (need_siglock) | |
| 743 | + spin_lock_irq(&child->sighand->siglock); | |
| 727 | 744 | child->exit_code = data; |
| 728 | 745 | wake_up_state(child, __TASK_TRACED); |
| 746 | + if (need_siglock) | |
| 747 | + spin_unlock_irq(&child->sighand->siglock); | |
| 729 | 748 | |
| 730 | 749 | return 0; |
| 731 | 750 | } |
| @@ -2992,11 +2992,9 @@ static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info) · 2991 unmodified lines | ||
| 2992 | 2992 | * Nor can they impersonate a kill()/tgkill(), which adds source info. |
| 2993 | 2993 | */ |
| 2994 | 2994 | if ((info->si_code >= 0 || info->si_code == SI_TKILL) && |
| 2995 | − (task_pid_vnr(current) != pid)) { | |
| 2996 | − /* We used to allow any < 0 si_code */ | |
| 2997 | − WARN_ON_ONCE(info->si_code < 0); | |
| 2995 | + (task_pid_vnr(current) != pid)) | |
| 2998 | 2996 | return -EPERM; |
| 2999 | − } | |
| 2997 | + | |
| 3000 | 2998 | info->si_signo = sig; |
| 3001 | 2999 | |
| 3002 | 3000 | /* POSIX.1b doesn't mention process groups. */ |
| @@ -3041,12 +3039,10 @@ static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) · 38 unmodified lines | ||
| 3041 | 3039 | /* Not even root can pretend to send signals from the kernel. |
| 3042 | 3040 | * Nor can they impersonate a kill()/tgkill(), which adds source info. |
| 3043 | 3041 | */ |
| 3044 | − if (((info->si_code >= 0 || info->si_code == SI_TKILL)) && | |
| 3045 | − (task_pid_vnr(current) != pid)) { | |
| 3046 | − /* We used to allow any < 0 si_code */ | |
| 3047 | − WARN_ON_ONCE(info->si_code < 0); | |
| 3042 | + if ((info->si_code >= 0 || info->si_code == SI_TKILL) && | |
| 3043 | + (task_pid_vnr(current) != pid)) | |
| 3048 | 3044 | return -EPERM; |
| 3049 | − } | |
| 3045 | + | |
| 3050 | 3046 | info->si_signo = sig; |
| 3051 | 3047 | |
| 3052 | 3048 | return do_send_specific(tgid, pid, sig, info); |
| @@ -1649,14 +1649,13 @@ SYSCALL_DEFINE1(umask, int, mask) · 1648 unmodified lines | ||
| 1649 | 1649 | return mask; |
| 1650 | 1650 | } |
| 1651 | 1651 | |
| 1652 | −static int prctl_set_mm_exe_file_locked(struct mm_struct *mm, unsigned int fd) | |
| 1652 | +static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | |
| 1653 | 1653 | { |
| 1654 | 1654 | struct fd exe; |
| 1655 | + struct file *old_exe, *exe_file; | |
| 1655 | 1656 | struct inode *inode; |
| 1656 | 1657 | int err; |
| 1657 | 1658 | |
| 1658 | − VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_sem), mm); | |
| 1659 | − | |
| 1660 | 1659 | exe = fdget(fd); |
| 1661 | 1660 | if (!exe.file) |
| 1662 | 1661 | return -EBADF; |
| @@ -1680,15 +1679,22 @@ static int prctl_set_mm_exe_file_locked(struct mm_struct *mm, unsigned int fd) · 17 unmodified lines | ||
| 1680 | 1679 | /* |
| 1681 | 1680 | * Forbid mm->exe_file change if old file still mapped. |
| 1682 | 1681 | */ |
| 1682 | + exe_file = get_mm_exe_file(mm); | |
| 1683 | 1683 | err = -EBUSY; |
| 1684 | − if (mm->exe_file) { | |
| 1684 | + if (exe_file) { | |
| 1685 | 1685 | struct vm_area_struct *vma; |
| 1686 | 1686 | |
| 1687 | − for (vma = mm->mmap; vma; vma = vma->vm_next) | |
| 1688 | − if (vma->vm_file && | |
| 1689 | − path_equal(&vma->vm_file->f_path, | |
| 1690 | − &mm->exe_file->f_path)) | |
| 1691 | − goto exit; | |
| 1687 | + down_read(&mm->mmap_sem); | |
| 1688 | + for (vma = mm->mmap; vma; vma = vma->vm_next) { | |
| 1689 | + if (!vma->vm_file) | |
| 1690 | + continue; | |
| 1691 | + if (path_equal(&vma->vm_file->f_path, | |
| 1692 | + &exe_file->f_path)) | |
| 1693 | + goto exit_err; | |
| 1694 | + } | |
| 1695 | + | |
| 1696 | + up_read(&mm->mmap_sem); | |
| 1697 | + fput(exe_file); | |
| 1692 | 1698 | } |
| 1693 | 1699 | |
| 1694 | 1700 | /* |
| @@ -1702,10 +1708,18 @@ static int prctl_set_mm_exe_file_locked(struct mm_struct *mm, unsigned int fd) · 7 unmodified lines | ||
| 1702 | 1708 | goto exit; |
| 1703 | 1709 | |
| 1704 | 1710 | err = 0; |
| 1705 | − set_mm_exe_file(mm, exe.file); /* this grabs a reference to exe.file */ | |
| 1711 | + /* set the new file, lockless */ | |
| 1712 | + get_file(exe.file); | |
| 1713 | + old_exe = xchg(&mm->exe_file, exe.file); | |
| 1714 | + if (old_exe) | |
| 1715 | + fput(old_exe); | |
| 1706 | 1716 | exit: |
| 1707 | 1717 | fdput(exe); |
| 1708 | 1718 | return err; |
| 1719 | +exit_err: | |
| 1720 | + up_read(&mm->mmap_sem); | |
| 1721 | + fput(exe_file); | |
| 1722 | + goto exit; | |
| 1709 | 1723 | } |
| 1710 | 1724 | |
| 1711 | 1725 | #ifdef CONFIG_CHECKPOINT_RESTORE |
| @@ -1840,10 +1854,9 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data · 128 unmodified lines | ||
| 1840 | 1854 | user_auxv[AT_VECTOR_SIZE - 1] = AT_NULL; |
| 1841 | 1855 | } |
| 1842 | 1856 | |
| 1843 | − down_write(&mm->mmap_sem); | |
| 1844 | 1857 | if (prctl_map.exe_fd != (u32)-1) |
| 1845 | − error = prctl_set_mm_exe_file_locked(mm, prctl_map.exe_fd); | |
| 1846 | − downgrade_write(&mm->mmap_sem); | |
| 1858 | + error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd); | |
| 1859 | + down_read(&mm->mmap_sem); | |
| 1847 | 1860 | if (error) |
| 1848 | 1861 | goto out; |
| 1849 | 1862 | |
| @@ -1909,12 +1922,8 @@ static int prctl_set_mm(int opt, unsigned long addr, · 59 unmodified lines | ||
| 1909 | 1922 | if (!capable(CAP_SYS_RESOURCE)) |
| 1910 | 1923 | return -EPERM; |
| 1911 | 1924 | |
| 1912 | − if (opt == PR_SET_MM_EXE_FILE) { | |
| 1913 | − down_write(&mm->mmap_sem); | |
| 1914 | − error = prctl_set_mm_exe_file_locked(mm, (unsigned int)addr); | |
| 1915 | − up_write(&mm->mmap_sem); | |
| 1916 | − return error; | |
| 1917 | − } | |
| 1925 | + if (opt == PR_SET_MM_EXE_FILE) | |
| 1926 | + return prctl_set_mm_exe_file(mm, (unsigned int)addr); | |
| 1918 | 1927 | |
| 1919 | 1928 | if (addr >= TASK_SIZE || addr < mmap_min_addr) |
| 1920 | 1929 | return -EINVAL; |
| @@ -93,11 +93,9 @@ · 92 unmodified lines | ||
| 93 | 93 | #include <linux/nmi.h> |
| 94 | 94 | #endif |
| 95 | 95 | |
| 96 | − | |
| 97 | 96 | #if defined(CONFIG_SYSCTL) |
| 98 | 97 | |
| 99 | 98 | /* External variables not in a header file. */ |
| 100 | −extern int max_threads; | |
| 101 | 99 | extern int suid_dumpable; |
| 102 | 100 | #ifdef CONFIG_COREDUMP |
| 103 | 101 | extern int core_uses_pid; |
| @@ -710,10 +708,10 @@ static struct ctl_table kern_table[] = { · 606 unmodified lines | ||
| 710 | 708 | #endif |
| 711 | 709 | { |
| 712 | 710 | .procname = "threads-max", |
| 713 | − .data = &max_threads, | |
| 711 | + .data = NULL, | |
| 714 | 712 | .maxlen = sizeof(int), |
| 715 | 713 | .mode = 0644, |
| 716 | − .proc_handler = proc_dointvec, | |
| 714 | + .proc_handler = sysctl_max_threads, | |
| 717 | 715 | }, |
| 718 | 716 | { |
| 719 | 717 | .procname = "random", |
| @@ -1983,7 +1981,15 @@ static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp, · 1263 unmodified lines | ||
| 1983 | 1981 | int write, void *data) |
| 1984 | 1982 | { |
| 1985 | 1983 | if (write) { |
| 1986 | − *valp = *negp ? -*lvalp : *lvalp; | |
| 1984 | + if (*negp) { | |
| 1985 | + if (*lvalp > (unsigned long) INT_MAX + 1) | |
| 1986 | + return -EINVAL; | |
| 1987 | + *valp = -*lvalp; | |
| 1988 | + } else { | |
| 1989 | + if (*lvalp > (unsigned long) INT_MAX) | |
| 1990 | + return -EINVAL; | |
| 1991 | + *valp = *lvalp; | |
| 1992 | + } | |
| 1987 | 1993 | } else { |
| 1988 | 1994 | int val = *valp; |
| 1989 | 1995 | if (val < 0) { |
| @@ -18,9 +18,8 @@ config HAVE_ARCH_BITREVERSE · 17 unmodified lines | ||
| 18 | 18 | default n |
| 19 | 19 | depends on BITREVERSE |
| 20 | 20 | help |
| 21 | − This option provides an config for the architecture which have instruction | |
| 22 | − can do bitreverse operation, we use the hardware instruction if the architecture | |
| 23 | − have this capability. | |
| 21 | + This option enables the use of hardware bit-reversal instructions on | |
| 22 | + architectures which support such operations. | |
| 24 | 23 | |
| 25 | 24 | config RATIONAL |
| 26 | 25 | bool |
| @@ -25,7 +25,7 @@ obj-y += lockref.o · 24 unmodified lines | ||
| 25 | 25 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ |
| 26 | 26 | bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \ |
| 27 | 27 | gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ |
| 28 | − bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \ | |
| 28 | + bsearch.o find_bit.o llist.o memweight.o kfifo.o \ | |
| 29 | 29 | percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o |
| 30 | 30 | obj-y += string_helpers.o |
| 31 | 31 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o |
| @@ -42,36 +42,6 @@ · 41 unmodified lines | ||
| 42 | 42 | * for the best explanations of this ordering. |
| 43 | 43 | */ |
| 44 | 44 | |
| 45 | −int __bitmap_empty(const unsigned long *bitmap, unsigned int bits) | |
| 46 | −{ | |
| 47 | − unsigned int k, lim = bits/BITS_PER_LONG; | |
| 48 | − for (k = 0; k < lim; ++k) | |
| 49 | − if (bitmap[k]) | |
| 50 | − return 0; | |
| 51 | − | |
| 52 | − if (bits % BITS_PER_LONG) | |
| 53 | − if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) | |
| 54 | − return 0; | |
| 55 | − | |
| 56 | − return 1; | |
| 57 | −} | |
| 58 | −EXPORT_SYMBOL(__bitmap_empty); | |
| 59 | − | |
| 60 | −int __bitmap_full(const unsigned long *bitmap, unsigned int bits) | |
| 61 | −{ | |
| 62 | − unsigned int k, lim = bits/BITS_PER_LONG; | |
| 63 | − for (k = 0; k < lim; ++k) | |
| 64 | − if (~bitmap[k]) | |
| 65 | − return 0; | |
| 66 | − | |
| 67 | − if (bits % BITS_PER_LONG) | |
| 68 | − if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) | |
| 69 | − return 0; | |
| 70 | − | |
| 71 | − return 1; | |
| 72 | −} | |
| 73 | −EXPORT_SYMBOL(__bitmap_full); | |
| 74 | − | |
| 75 | 45 | int __bitmap_equal(const unsigned long *bitmap1, |
| 76 | 46 | const unsigned long *bitmap2, unsigned int bits) |
| 77 | 47 | { |
| @@ -37,10 +37,11 @@ EXPORT_SYMBOL(__next_cpu_nr); · 36 unmodified lines | ||
| 37 | 37 | int cpumask_next_and(int n, const struct cpumask *src1p, |
| 38 | 38 | const struct cpumask *src2p) |
| 39 | 39 | { |
| 40 | − while ((n = cpumask_next(n, src1p)) < nr_cpu_ids) | |
| 41 | − if (cpumask_test_cpu(n, src2p)) | |
| 42 | − break; | |
| 43 | − return n; | |
| 40 | + struct cpumask tmp; | |
| 41 | + | |
| 42 | + if (cpumask_and(&tmp, src1p, src2p)) | |
| 43 | + return cpumask_next(n, &tmp); | |
| 44 | + return nr_cpu_ids; | |
| 44 | 45 | } |
| 45 | 46 | EXPORT_SYMBOL(cpumask_next_and); |
| 46 | 47 | |
| @@ -361,7 +361,7 @@ static struct dma_debug_entry *bucket_find_contain(struct hash_bucket **bucket, · 360 unmodified lines | ||
| 361 | 361 | unsigned int range = 0; |
| 362 | 362 | |
| 363 | 363 | while (range <= max_range) { |
| 364 | − entry = __hash_bucket_find(*bucket, &index, containing_match); | |
| 364 | + entry = __hash_bucket_find(*bucket, ref, containing_match); | |
| 365 | 365 | |
| 366 | 366 | if (entry) |
| 367 | 367 | return entry; |
| @@ -0,0 +1,193 @@ | ||
| 1 | +/* bit search implementation | |
| 2 | + * | |
| 3 | + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | |
| 4 | + * Written by David Howells (dhowells@redhat.com) | |
| 5 | + * | |
| 6 | + * Copyright (C) 2008 IBM Corporation | |
| 7 | + * 'find_last_bit' is written by Rusty Russell <rusty@rustcorp.com.au> | |
| 8 | + * (Inspired by David Howell's find_next_bit implementation) | |
| 9 | + * | |
| 10 | + * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease | |
| 11 | + * size and improve performance, 2015. | |
| 12 | + * | |
| 13 | + * This program is free software; you can redistribute it and/or | |
| 14 | + * modify it under the terms of the GNU General Public License | |
| 15 | + * as published by the Free Software Foundation; either version | |
| 16 | + * 2 of the License, or (at your option) any later version. | |
| 17 | + */ | |
| 18 | + | |
| 19 | +#include <linux/bitops.h> | |
| 20 | +#include <linux/bitmap.h> | |
| 21 | +#include <linux/export.h> | |
| 22 | +#include <linux/kernel.h> | |
| 23 | + | |
| 24 | +#if !defined(find_next_bit) || !defined(find_next_zero_bit) | |
| 25 | + | |
| 26 | +/* | |
| 27 | + * This is a common helper function for find_next_bit and | |
| 28 | + * find_next_zero_bit. The difference is the "invert" argument, which | |
| 29 | + * is XORed with each fetched word before searching it for one bits. | |
| 30 | + */ | |
| 31 | +static unsigned long _find_next_bit(const unsigned long *addr, | |
| 32 | + unsigned long nbits, unsigned long start, unsigned long invert) | |
| 33 | +{ | |
| 34 | + unsigned long tmp; | |
| 35 | + | |
| 36 | + if (!nbits || start >= nbits) | |
| 37 | + return nbits; | |
| 38 | + | |
| 39 | + tmp = addr[start / BITS_PER_LONG] ^ invert; | |
| 40 | + | |
| 41 | + /* Handle 1st word. */ | |
| 42 | + tmp &= BITMAP_FIRST_WORD_MASK(start); | |
| 43 | + start = round_down(start, BITS_PER_LONG); | |
| 44 | + | |
| 45 | + while (!tmp) { | |
| 46 | + start += BITS_PER_LONG; | |
| 47 | + if (start >= nbits) | |
| 48 | + return nbits; | |
| 49 | + | |
| 50 | + tmp = addr[start / BITS_PER_LONG] ^ invert; | |
| 51 | + } | |
| 52 | + | |
| 53 | + return min(start + __ffs(tmp), nbits); | |
| 54 | +} | |
| 55 | +#endif | |
| 56 | + | |
| 57 | +#ifndef find_next_bit | |
| 58 | +/* | |
| 59 | + * Find the next set bit in a memory region. | |
| 60 | + */ | |
| 61 | +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, | |
| 62 | + unsigned long offset) | |
| 63 | +{ | |
| 64 | + return _find_next_bit(addr, size, offset, 0UL); | |
| 65 | +} | |
| 66 | +EXPORT_SYMBOL(find_next_bit); | |
| 67 | +#endif | |
| 68 | + | |
| 69 | +#ifndef find_next_zero_bit | |
| 70 | +unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, | |
| 71 | + unsigned long offset) | |
| 72 | +{ | |
| 73 | + return _find_next_bit(addr, size, offset, ~0UL); | |
| 74 | +} | |
| 75 | +EXPORT_SYMBOL(find_next_zero_bit); | |
| 76 | +#endif | |
| 77 | + | |
| 78 | +#ifndef find_first_bit | |
| 79 | +/* | |
| 80 | + * Find the first set bit in a memory region. | |
| 81 | + */ | |
| 82 | +unsigned long find_first_bit(const unsigned long *addr, unsigned long size) | |
| 83 | +{ | |
| 84 | + unsigned long idx; | |
| 85 | + | |
| 86 | + for (idx = 0; idx * BITS_PER_LONG < size; idx++) { | |
| 87 | + if (addr[idx]) | |
| 88 | + return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size); | |
| 89 | + } | |
| 90 | + | |
| 91 | + return size; | |
| 92 | +} | |
| 93 | +EXPORT_SYMBOL(find_first_bit); | |
| 94 | +#endif | |
| 95 | + | |
| 96 | +#ifndef find_first_zero_bit | |
| 97 | +/* | |
| 98 | + * Find the first cleared bit in a memory region. | |
| 99 | + */ | |
| 100 | +unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) | |
| 101 | +{ | |
| 102 | + unsigned long idx; | |
| 103 | + | |
| 104 | + for (idx = 0; idx * BITS_PER_LONG < size; idx++) { | |
| 105 | + if (addr[idx] != ~0UL) | |
| 106 | + return min(idx * BITS_PER_LONG + ffz(addr[idx]), size); | |
| 107 | + } | |
| 108 | + | |
| 109 | + return size; | |
| 110 | +} | |
| 111 | +EXPORT_SYMBOL(find_first_zero_bit); | |
| 112 | +#endif | |
| 113 | + | |
| 114 | +#ifndef find_last_bit | |
| 115 | +unsigned long find_last_bit(const unsigned long *addr, unsigned long size) | |
| 116 | +{ | |
| 117 | + if (size) { | |
| 118 | + unsigned long val = BITMAP_LAST_WORD_MASK(size); | |
| 119 | + unsigned long idx = (size-1) / BITS_PER_LONG; | |
| 120 | + | |
| 121 | + do { | |
| 122 | + val &= addr[idx]; | |
| 123 | + if (val) | |
| 124 | + return idx * BITS_PER_LONG + __fls(val); | |
| 125 | + | |
| 126 | + val = ~0ul; | |
| 127 | + } while (idx--); | |
| 128 | + } | |
| 129 | + return size; | |
| 130 | +} | |
| 131 | +EXPORT_SYMBOL(find_last_bit); | |
| 132 | +#endif | |
| 133 | + | |
| 134 | +#ifdef __BIG_ENDIAN | |
| 135 | + | |
| 136 | +/* include/linux/byteorder does not support "unsigned long" type */ | |
| 137 | +static inline unsigned long ext2_swab(const unsigned long y) | |
| 138 | +{ | |
| 139 | +#if BITS_PER_LONG == 64 | |
| 140 | + return (unsigned long) __swab64((u64) y); | |
| 141 | +#elif BITS_PER_LONG == 32 | |
| 142 | + return (unsigned long) __swab32((u32) y); | |
| 143 | +#else | |
| 144 | +#error BITS_PER_LONG not defined | |
| 145 | +#endif | |
| 146 | +} | |
| 147 | + | |
| 148 | +#if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le) | |
| 149 | +static unsigned long _find_next_bit_le(const unsigned long *addr, | |
| 150 | + unsigned long nbits, unsigned long start, unsigned long invert) | |
| 151 | +{ | |
| 152 | + unsigned long tmp; | |
| 153 | + | |
| 154 | + if (!nbits || start >= nbits) | |
| 155 | + return nbits; | |
| 156 | + | |
| 157 | + tmp = addr[start / BITS_PER_LONG] ^ invert; | |
| 158 | + | |
| 159 | + /* Handle 1st word. */ | |
| 160 | + tmp &= ext2_swab(BITMAP_FIRST_WORD_MASK(start)); | |
| 161 | + start = round_down(start, BITS_PER_LONG); | |
| 162 | + | |
| 163 | + while (!tmp) { | |
| 164 | + start += BITS_PER_LONG; | |
| 165 | + if (start >= nbits) | |
| 166 | + return nbits; | |
| 167 | + | |
| 168 | + tmp = addr[start / BITS_PER_LONG] ^ invert; | |
| 169 | + } | |
| 170 | + | |
| 171 | + return min(start + __ffs(ext2_swab(tmp)), nbits); | |
| 172 | +} | |
| 173 | +#endif | |
| 174 | + | |
| 175 | +#ifndef find_next_zero_bit_le | |
| 176 | +unsigned long find_next_zero_bit_le(const void *addr, unsigned | |
| 177 | + long size, unsigned long offset) | |
| 178 | +{ | |
| 179 | + return _find_next_bit_le(addr, size, offset, ~0UL); | |
| 180 | +} | |
| 181 | +EXPORT_SYMBOL(find_next_zero_bit_le); | |
| 182 | +#endif | |
| 183 | + | |
| 184 | +#ifndef find_next_bit_le | |
| 185 | +unsigned long find_next_bit_le(const void *addr, unsigned | |
| 186 | + long size, unsigned long offset) | |
| 187 | +{ | |
| 188 | + return _find_next_bit_le(addr, size, offset, 0UL); | |
| 189 | +} | |
| 190 | +EXPORT_SYMBOL(find_next_bit_le); | |
| 191 | +#endif | |
| 192 | + | |
| 193 | +#endif /* __BIG_ENDIAN */ | |
| @@ -4,6 +4,9 @@ · 3 unmodified lines | ||
| 4 | 4 | * Written by Rusty Russell <rusty@rustcorp.com.au> |
| 5 | 5 | * (Inspired by David Howell's find_next_bit implementation) |
| 6 | 6 | * |
| 7 | + * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease | |
| 8 | + * size and improve performance, 2015. | |
| 9 | + * | |
| 7 | 10 | * This program is free software; you can redistribute it and/or |
| 8 | 11 | * modify it under the terms of the GNU General Public License |
| 9 | 12 | * as published by the Free Software Foundation; either version |
| @@ -11,37 +14,26 @@ · 1 unmodified line | ||
| 11 | 14 | */ |
| 12 | 15 | |
| 13 | 16 | #include <linux/bitops.h> |
| 17 | +#include <linux/bitmap.h> | |
| 14 | 18 | #include <linux/export.h> |
| 15 | −#include <asm/types.h> | |
| 16 | −#include <asm/byteorder.h> | |
| 19 | +#include <linux/kernel.h> | |
| 17 | 20 | |
| 18 | 21 | #ifndef find_last_bit |
| 19 | 22 | |
| 20 | 23 | unsigned long find_last_bit(const unsigned long *addr, unsigned long size) |
| 21 | 24 | { |
| 22 | − unsigned long words; | |
| 23 | − unsigned long tmp; | |
| 24 | − | |
| 25 | − /* Start at final word. */ | |
| 26 | − words = size / BITS_PER_LONG; | |
| 25 | + if (size) { | |
| 26 | + unsigned long val = BITMAP_LAST_WORD_MASK(size); | |
| 27 | + unsigned long idx = (size-1) / BITS_PER_LONG; | |
| 27 | 28 | |
| 28 | − /* Partial final word? */ | |
| 29 | − if (size & (BITS_PER_LONG-1)) { | |
| 30 | − tmp = (addr[words] & (~0UL >> (BITS_PER_LONG | |
| 31 | − - (size & (BITS_PER_LONG-1))))); | |
| 32 | − if (tmp) | |
| 33 | − goto found; | |
| 34 | − } | |
| 29 | + do { | |
| 30 | + val &= addr[idx]; | |
| 31 | + if (val) | |
| 32 | + return idx * BITS_PER_LONG + __fls(val); | |
| 35 | 33 | |
| 36 | − while (words) { | |
| 37 | − tmp = addr[--words]; | |
| 38 | − if (tmp) { | |
| 39 | −found: | |
| 40 | − return words * BITS_PER_LONG + __fls(tmp); | |
| 41 | − } | |
| 34 | + val = ~0ul; | |
| 35 | + } while (idx--); | |
| 42 | 36 | } |
| 43 | − | |
| 44 | − /* Not found */ | |
| 45 | 37 | return size; |
| 46 | 38 | } |
| 47 | 39 | EXPORT_SYMBOL(find_last_bit); |
| @@ -1,285 +0,0 @@ | ||
| 1 | −/* find_next_bit.c: fallback find next bit implementation | |
| 2 | − * | |
| 3 | − * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | |
| 4 | − * Written by David Howells (dhowells@redhat.com) | |
| 5 | − * | |
| 6 | − * This program is free software; you can redistribute it and/or | |
| 7 | − * modify it under the terms of the GNU General Public License | |
| 8 | − * as published by the Free Software Foundation; either version | |
| 9 | − * 2 of the License, or (at your option) any later version. | |
| 10 | − */ | |
| 11 | − | |
| 12 | −#include <linux/bitops.h> | |
| 13 | −#include <linux/export.h> | |
| 14 | −#include <asm/types.h> | |
| 15 | −#include <asm/byteorder.h> | |
| 16 | − | |
| 17 | −#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) | |
| 18 | − | |
| 19 | −#ifndef find_next_bit | |
| 20 | −/* | |
| 21 | − * Find the next set bit in a memory region. | |
| 22 | − */ | |
| 23 | −unsigned long find_next_bit(const unsigned long *addr, unsigned long size, | |
| 24 | − unsigned long offset) | |
| 25 | −{ | |
| 26 | − const unsigned long *p = addr + BITOP_WORD(offset); | |
| 27 | − unsigned long result = offset & ~(BITS_PER_LONG-1); | |
| 28 | − unsigned long tmp; | |
| 29 | − | |
| 30 | − if (offset >= size) | |
| 31 | − return size; | |
| 32 | − size -= result; | |
| 33 | − offset %= BITS_PER_LONG; | |
| 34 | − if (offset) { | |
| 35 | − tmp = *(p++); | |
| 36 | − tmp &= (~0UL << offset); | |
| 37 | − if (size < BITS_PER_LONG) | |
| 38 | − goto found_first; | |
| 39 | − if (tmp) | |
| 40 | − goto found_middle; | |
| 41 | − size -= BITS_PER_LONG; | |
| 42 | − result += BITS_PER_LONG; | |
| 43 | − } | |
| 44 | − while (size & ~(BITS_PER_LONG-1)) { | |
| 45 | − if ((tmp = *(p++))) | |
| 46 | − goto found_middle; | |
| 47 | − result += BITS_PER_LONG; | |
| 48 | − size -= BITS_PER_LONG; | |
| 49 | − } | |
| 50 | − if (!size) | |
| 51 | − return result; | |
| 52 | − tmp = *p; | |
| 53 | − | |
| 54 | −found_first: | |
| 55 | − tmp &= (~0UL >> (BITS_PER_LONG - size)); | |
| 56 | − if (tmp == 0UL) /* Are any bits set? */ | |
| 57 | − return result + size; /* Nope. */ | |
| 58 | −found_middle: | |
| 59 | − return result + __ffs(tmp); | |
| 60 | −} | |
| 61 | −EXPORT_SYMBOL(find_next_bit); | |
| 62 | −#endif | |
| 63 | − | |
| 64 | −#ifndef find_next_zero_bit | |
| 65 | −/* | |
| 66 | − * This implementation of find_{first,next}_zero_bit was stolen from | |
| 67 | − * Linus' asm-alpha/bitops.h. | |
| 68 | − */ | |
| 69 | −unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, | |
| 70 | − unsigned long offset) | |
| 71 | −{ | |
| 72 | − const unsigned long *p = addr + BITOP_WORD(offset); | |
| 73 | − unsigned long result = offset & ~(BITS_PER_LONG-1); | |
| 74 | − unsigned long tmp; | |
| 75 | − | |
| 76 | − if (offset >= size) | |
| 77 | − return size; | |
| 78 | − size -= result; | |
| 79 | − offset %= BITS_PER_LONG; | |
| 80 | − if (offset) { | |
| 81 | − tmp = *(p++); | |
| 82 | − tmp |= ~0UL >> (BITS_PER_LONG - offset); | |
| 83 | − if (size < BITS_PER_LONG) | |
| 84 | − goto found_first; | |
| 85 | − if (~tmp) | |
| 86 | − goto found_middle; | |
| 87 | − size -= BITS_PER_LONG; | |
| 88 | − result += BITS_PER_LONG; | |
| 89 | − } | |
| 90 | − while (size & ~(BITS_PER_LONG-1)) { | |
| 91 | − if (~(tmp = *(p++))) | |
| 92 | − goto found_middle; | |
| 93 | − result += BITS_PER_LONG; | |
| 94 | − size -= BITS_PER_LONG; | |
| 95 | − } | |
| 96 | − if (!size) | |
| 97 | − return result; | |
| 98 | − tmp = *p; | |
| 99 | − | |
| 100 | −found_first: | |
| 101 | − tmp |= ~0UL << size; | |
| 102 | − if (tmp == ~0UL) /* Are any bits zero? */ | |
| 103 | − return result + size; /* Nope. */ | |
| 104 | −found_middle: | |
| 105 | − return result + ffz(tmp); | |
| 106 | −} | |
| 107 | −EXPORT_SYMBOL(find_next_zero_bit); | |
| 108 | −#endif | |
| 109 | − | |
| 110 | −#ifndef find_first_bit | |
| 111 | −/* | |
| 112 | − * Find the first set bit in a memory region. | |
| 113 | − */ | |
| 114 | −unsigned long find_first_bit(const unsigned long *addr, unsigned long size) | |
| 115 | −{ | |
| 116 | − const unsigned long *p = addr; | |
| 117 | − unsigned long result = 0; | |
| 118 | − unsigned long tmp; | |
| 119 | − | |
| 120 | − while (size & ~(BITS_PER_LONG-1)) { | |
| 121 | − if ((tmp = *(p++))) | |
| 122 | − goto found; | |
| 123 | − result += BITS_PER_LONG; | |
| 124 | − size -= BITS_PER_LONG; | |
| 125 | − } | |
| 126 | − if (!size) | |
| 127 | − return result; | |
| 128 | − | |
| 129 | − tmp = (*p) & (~0UL >> (BITS_PER_LONG - size)); | |
| 130 | − if (tmp == 0UL) /* Are any bits set? */ | |
| 131 | − return result + size; /* Nope. */ | |
| 132 | −found: | |
| 133 | − return result + __ffs(tmp); | |
| 134 | −} | |
| 135 | −EXPORT_SYMBOL(find_first_bit); | |
| 136 | −#endif | |
| 137 | − | |
| 138 | −#ifndef find_first_zero_bit | |
| 139 | −/* | |
| 140 | − * Find the first cleared bit in a memory region. | |
| 141 | − */ | |
| 142 | −unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) | |
| 143 | −{ | |
| 144 | − const unsigned long *p = addr; | |
| 145 | − unsigned long result = 0; | |
| 146 | − unsigned long tmp; | |
| 147 | − | |
| 148 | − while (size & ~(BITS_PER_LONG-1)) { | |
| 149 | − if (~(tmp = *(p++))) | |
| 150 | − goto found; | |
| 151 | − result += BITS_PER_LONG; | |
| 152 | − size -= BITS_PER_LONG; | |
| 153 | − } | |
| 154 | − if (!size) | |
| 155 | − return result; | |
| 156 | − | |
| 157 | − tmp = (*p) | (~0UL << size); | |
| 158 | − if (tmp == ~0UL) /* Are any bits zero? */ | |
| 159 | − return result + size; /* Nope. */ | |
| 160 | −found: | |
| 161 | − return result + ffz(tmp); | |
| 162 | −} | |
| 163 | −EXPORT_SYMBOL(find_first_zero_bit); | |
| 164 | −#endif | |
| 165 | − | |
| 166 | −#ifdef __BIG_ENDIAN | |
| 167 | − | |
| 168 | −/* include/linux/byteorder does not support "unsigned long" type */ | |
| 169 | −static inline unsigned long ext2_swabp(const unsigned long * x) | |
| 170 | −{ | |
| 171 | −#if BITS_PER_LONG == 64 | |
| 172 | − return (unsigned long) __swab64p((u64 *) x); | |
| 173 | −#elif BITS_PER_LONG == 32 | |
| 174 | − return (unsigned long) __swab32p((u32 *) x); | |
| 175 | −#else | |
| 176 | −#error BITS_PER_LONG not defined | |
| 177 | −#endif | |
| 178 | −} | |
| 179 | − | |
| 180 | −/* include/linux/byteorder doesn't support "unsigned long" type */ | |
| 181 | −static inline unsigned long ext2_swab(const unsigned long y) | |
| 182 | −{ | |
| 183 | −#if BITS_PER_LONG == 64 | |
| 184 | − return (unsigned long) __swab64((u64) y); | |
| 185 | −#elif BITS_PER_LONG == 32 | |
| 186 | − return (unsigned long) __swab32((u32) y); | |
| 187 | −#else | |
| 188 | −#error BITS_PER_LONG not defined | |
| 189 | −#endif | |
| 190 | −} | |
| 191 | − | |
| 192 | −#ifndef find_next_zero_bit_le | |
| 193 | −unsigned long find_next_zero_bit_le(const void *addr, unsigned | |
| 194 | − long size, unsigned long offset) | |
| 195 | −{ | |
| 196 | − const unsigned long *p = addr; | |
| 197 | − unsigned long result = offset & ~(BITS_PER_LONG - 1); | |
| 198 | − unsigned long tmp; | |
| 199 | − | |
| 200 | − if (offset >= size) | |
| 201 | − return size; | |
| 202 | − p += BITOP_WORD(offset); | |
| 203 | − size -= result; | |
| 204 | − offset &= (BITS_PER_LONG - 1UL); | |
| 205 | − if (offset) { | |
| 206 | − tmp = ext2_swabp(p++); | |
| 207 | − tmp |= (~0UL >> (BITS_PER_LONG - offset)); | |
| 208 | − if (size < BITS_PER_LONG) | |
| 209 | − goto found_first; | |
| 210 | − if (~tmp) | |
| 211 | − goto found_middle; | |
| 212 | − size -= BITS_PER_LONG; | |
| 213 | − result += BITS_PER_LONG; | |
| 214 | − } | |
| 215 | − | |
| 216 | − while (size & ~(BITS_PER_LONG - 1)) { | |
| 217 | − if (~(tmp = *(p++))) | |
| 218 | − goto found_middle_swap; | |
| 219 | − result += BITS_PER_LONG; | |
| 220 | − size -= BITS_PER_LONG; | |
| 221 | − } | |
| 222 | − if (!size) | |
| 223 | − return result; | |
| 224 | − tmp = ext2_swabp(p); | |
| 225 | −found_first: | |
| 226 | − tmp |= ~0UL << size; | |
| 227 | − if (tmp == ~0UL) /* Are any bits zero? */ | |
| 228 | − return result + size; /* Nope. Skip ffz */ | |
| 229 | −found_middle: | |
| 230 | − return result + ffz(tmp); | |
| 231 | − | |
| 232 | −found_middle_swap: | |
| 233 | − return result + ffz(ext2_swab(tmp)); | |
| 234 | −} | |
| 235 | −EXPORT_SYMBOL(find_next_zero_bit_le); | |
| 236 | −#endif | |
| 237 | − | |
| 238 | −#ifndef find_next_bit_le | |
| 239 | −unsigned long find_next_bit_le(const void *addr, unsigned | |
| 240 | − long size, unsigned long offset) | |
| 241 | −{ | |
| 242 | − const unsigned long *p = addr; | |
| 243 | − unsigned long result = offset & ~(BITS_PER_LONG - 1); | |
| 244 | − unsigned long tmp; | |
| 245 | − | |
| 246 | − if (offset >= size) | |
| 247 | − return size; | |
| 248 | − p += BITOP_WORD(offset); | |
| 249 | − size -= result; | |
| 250 | − offset &= (BITS_PER_LONG - 1UL); | |
| 251 | − if (offset) { | |
| 252 | − tmp = ext2_swabp(p++); | |
| 253 | − tmp &= (~0UL << offset); | |
| 254 | − if (size < BITS_PER_LONG) | |
| 255 | − goto found_first; | |
| 256 | − if (tmp) | |
| 257 | − goto found_middle; | |
| 258 | − size -= BITS_PER_LONG; | |
| 259 | − result += BITS_PER_LONG; | |
| 260 | − } | |
| 261 | − | |
| 262 | − while (size & ~(BITS_PER_LONG - 1)) { | |
| 263 | − tmp = *(p++); | |
| 264 | − if (tmp) | |
| 265 | − goto found_middle_swap; | |
| 266 | − result += BITS_PER_LONG; | |
| 267 | − size -= BITS_PER_LONG; | |
| 268 | − } | |
| 269 | − if (!size) | |
| 270 | − return result; | |
| 271 | − tmp = ext2_swabp(p); | |
| 272 | −found_first: | |
| 273 | − tmp &= (~0UL >> (BITS_PER_LONG - size)); | |
| 274 | − if (tmp == 0UL) /* Are any bits set? */ | |
| 275 | − return result + size; /* Nope. */ | |
| 276 | −found_middle: | |
| 277 | − return result + __ffs(tmp); | |
| 278 | − | |
| 279 | −found_middle_swap: | |
| 280 | − return result + __ffs(ext2_swab(tmp)); | |
| 281 | −} | |
| 282 | −EXPORT_SYMBOL(find_next_bit_le); | |
| 283 | −#endif | |
| 284 | − | |
| 285 | −#endif /* __BIG_ENDIAN */ | |
| @@ -33,6 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #include <asm/page.h> /* for PAGE_SIZE */ |
| 35 | 35 | #include <asm/sections.h> /* for dereference_function_descriptor() */ |
| 36 | +#include <asm/byteorder.h> /* cpu_to_le16 */ | |
| 36 | 37 | |
| 37 | 38 | #include <linux/string_helpers.h> |
| 38 | 39 | #include "kstrtox.h" |
| @@ -122,142 +123,145 @@ int skip_atoi(const char **s) · 83 unmodified lines | ||
| 122 | 123 | return i; |
| 123 | 124 | } |
| 124 | 125 | |
| 125 | −/* Decimal conversion is by far the most typical, and is used | |
| 126 | − * for /proc and /sys data. This directly impacts e.g. top performance | |
| 127 | − * with many processes running. We optimize it for speed | |
| 128 | − * using ideas described at <http://www.cs.uiowa.edu/~jones/bcd/divide.html> | |
| 129 | − * (with permission from the author, Douglas W. Jones). | |
| 126 | +/* | |
| 127 | + * Decimal conversion is by far the most typical, and is used for | |
| 128 | + * /proc and /sys data. This directly impacts e.g. top performance | |
| 129 | + * with many processes running. We optimize it for speed by emitting | |
| 130 | + * two characters at a time, using a 200 byte lookup table. This | |
| 131 | + * roughly halves the number of multiplications compared to computing | |
| 132 | + * the digits one at a time. Implementation strongly inspired by the | |
| 133 | + * previous version, which in turn used ideas described at | |
| 134 | + * <http://www.cs.uiowa.edu/~jones/bcd/divide.html> (with permission | |
| 135 | + * from the author, Douglas W. Jones). | |
| 136 | + * | |
| 137 | + * It turns out there is precisely one 26 bit fixed-point | |
| 138 | + * approximation a of 64/100 for which x/100 == (x * (u64)a) >> 32 | |
| 139 | + * holds for all x in [0, 10^8-1], namely a = 0x28f5c29. The actual | |
| 140 | + * range happens to be somewhat larger (x <= 1073741898), but that's | |
| 141 | + * irrelevant for our purpose. | |
| 142 | + * | |
| 143 | + * For dividing a number in the range [10^4, 10^6-1] by 100, we still | |
| 144 | + * need a 32x32->64 bit multiply, so we simply use the same constant. | |
| 145 | + * | |
| 146 | + * For dividing a number in the range [100, 10^4-1] by 100, there are | |
| 147 | + * several options. The simplest is (x * 0x147b) >> 19, which is valid | |
| 148 | + * for all x <= 43698. | |
| 130 | 149 | */ |
| 131 | 150 | |
| 132 | −#if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64 | |
| 133 | −/* Formats correctly any integer in [0, 999999999] */ | |
| 151 | +static const u16 decpair[100] = { | |
| 152 | +#define _(x) (__force u16) cpu_to_le16(((x % 10) | ((x / 10) << 8)) + 0x3030) | |
| 153 | + _( 0), _( 1), _( 2), _( 3), _( 4), _( 5), _( 6), _( 7), _( 8), _( 9), | |
| 154 | + _(10), _(11), _(12), _(13), _(14), _(15), _(16), _(17), _(18), _(19), | |
| 155 | + _(20), _(21), _(22), _(23), _(24), _(25), _(26), _(27), _(28), _(29), | |
| 156 | + _(30), _(31), _(32), _(33), _(34), _(35), _(36), _(37), _(38), _(39), | |
| 157 | + _(40), _(41), _(42), _(43), _(44), _(45), _(46), _(47), _(48), _(49), | |
| 158 | + _(50), _(51), _(52), _(53), _(54), _(55), _(56), _(57), _(58), _(59), | |
| 159 | + _(60), _(61), _(62), _(63), _(64), _(65), _(66), _(67), _(68), _(69), | |
| 160 | + _(70), _(71), _(72), _(73), _(74), _(75), _(76), _(77), _(78), _(79), | |
| 161 | + _(80), _(81), _(82), _(83), _(84), _(85), _(86), _(87), _(88), _(89), | |
| 162 | + _(90), _(91), _(92), _(93), _(94), _(95), _(96), _(97), _(98), _(99), | |
| 163 | +#undef _ | |
| 164 | +}; | |
| 165 | + | |
| 166 | +/* | |
| 167 | + * This will print a single '0' even if r == 0, since we would | |
| 168 | + * immediately jump to out_r where two 0s would be written but only | |
| 169 | + * one of them accounted for in buf. This is needed by ip4_string | |
| 170 | + * below. All other callers pass a non-zero value of r. | |
| 171 | +*/ | |
| 134 | 172 | static noinline_for_stack |
| 135 | −char *put_dec_full9(char *buf, unsigned q) | |
| 173 | +char *put_dec_trunc8(char *buf, unsigned r) | |
| 136 | 174 | { |
| 137 | − unsigned r; | |
| 175 | + unsigned q; | |
| 138 | 176 | |
| 139 | − /* | |
| 140 | − * Possible ways to approx. divide by 10 | |
| 141 | − * (x * 0x1999999a) >> 32 x < 1073741829 (multiply must be 64-bit) | |
| 142 | − * (x * 0xcccd) >> 19 x < 81920 (x < 262149 when 64-bit mul) | |
| 143 | − * (x * 0x6667) >> 18 x < 43699 | |
| 144 | − * (x * 0x3334) >> 17 x < 16389 | |
| 145 | − * (x * 0x199a) >> 16 x < 16389 | |
| 146 | − * (x * 0x0ccd) >> 15 x < 16389 | |
| 147 | − * (x * 0x0667) >> 14 x < 2739 | |
| 148 | − * (x * 0x0334) >> 13 x < 1029 | |
| 149 | − * (x * 0x019a) >> 12 x < 1029 | |
| 150 | − * (x * 0x00cd) >> 11 x < 1029 shorter code than * 0x67 (on i386) | |
| 151 | − * (x * 0x0067) >> 10 x < 179 | |
| 152 | − * (x * 0x0034) >> 9 x < 69 same | |
| 153 | − * (x * 0x001a) >> 8 x < 69 same | |
| 154 | − * (x * 0x000d) >> 7 x < 69 same, shortest code (on i386) | |
| 155 | − * (x * 0x0007) >> 6 x < 19 | |
| 156 | − * See <http://www.cs.uiowa.edu/~jones/bcd/divide.html> | |
| 157 | − */ | |
| 158 | − r = (q * (uint64_t)0x1999999a) >> 32; | |
| 159 | − *buf++ = (q - 10 * r) + '0'; /* 1 */ | |
| 160 | − q = (r * (uint64_t)0x1999999a) >> 32; | |
| 161 | − *buf++ = (r - 10 * q) + '0'; /* 2 */ | |
| 162 | − r = (q * (uint64_t)0x1999999a) >> 32; | |
| 163 | − *buf++ = (q - 10 * r) + '0'; /* 3 */ | |
| 164 | − q = (r * (uint64_t)0x1999999a) >> 32; | |
| 165 | − *buf++ = (r - 10 * q) + '0'; /* 4 */ | |
| 166 | − r = (q * (uint64_t)0x1999999a) >> 32; | |
| 167 | − *buf++ = (q - 10 * r) + '0'; /* 5 */ | |
| 168 | − /* Now value is under 10000, can avoid 64-bit multiply */ | |
| 169 | − q = (r * 0x199a) >> 16; | |
| 170 | − *buf++ = (r - 10 * q) + '0'; /* 6 */ | |
| 171 | − r = (q * 0xcd) >> 11; | |
| 172 | − *buf++ = (q - 10 * r) + '0'; /* 7 */ | |
| 173 | − q = (r * 0xcd) >> 11; | |
| 174 | − *buf++ = (r - 10 * q) + '0'; /* 8 */ | |
| 175 | − *buf++ = q + '0'; /* 9 */ | |
| 177 | + /* 1 <= r < 10^8 */ | |
| 178 | + if (r < 100) | |
| 179 | + goto out_r; | |
| 180 | + | |
| 181 | + /* 100 <= r < 10^8 */ | |
| 182 | + q = (r * (u64)0x28f5c29) >> 32; | |
| 183 | + *((u16 *)buf) = decpair[r - 100*q]; | |
| 184 | + buf += 2; | |
| 185 | + | |
| 186 | + /* 1 <= q < 10^6 */ | |
| 187 | + if (q < 100) | |
| 188 | + goto out_q; | |
| 189 | + | |
| 190 | + /* 100 <= q < 10^6 */ | |
| 191 | + r = (q * (u64)0x28f5c29) >> 32; | |
| 192 | + *((u16 *)buf) = decpair[q - 100*r]; | |
| 193 | + buf += 2; | |
| 194 | + | |
| 195 | + /* 1 <= r < 10^4 */ | |
| 196 | + if (r < 100) | |
| 197 | + goto out_r; | |
| 198 | + | |
| 199 | + /* 100 <= r < 10^4 */ | |
| 200 | + q = (r * 0x147b) >> 19; | |
| 201 | + *((u16 *)buf) = decpair[r - 100*q]; | |
| 202 | + buf += 2; | |
| 203 | +out_q: | |
| 204 | + /* 1 <= q < 100 */ | |
| 205 | + r = q; | |
| 206 | +out_r: | |
| 207 | + /* 1 <= r < 100 */ | |
| 208 | + *((u16 *)buf) = decpair[r]; | |
| 209 | + buf += r < 10 ? 1 : 2; | |
| 176 | 210 | return buf; |
| 177 | 211 | } |
| 178 | −#endif | |
| 179 | 212 | |
| 180 | −/* Similar to above but do not pad with zeros. | |
| 181 | − * Code can be easily arranged to print 9 digits too, but our callers | |
| 182 | − * always call put_dec_full9() instead when the number has 9 decimal digits. | |
| 183 | − */ | |
| 213 | +#if BITS_PER_LONG == 64 && BITS_PER_LONG_LONG == 64 | |
| 184 | 214 | static noinline_for_stack |
| 185 | −char *put_dec_trunc8(char *buf, unsigned r) | |
| 215 | +char *put_dec_full8(char *buf, unsigned r) | |
| 186 | 216 | { |
| 187 | 217 | unsigned q; |
| 188 | 218 | |
| 189 | − /* Copy of previous function's body with added early returns */ | |
| 190 | − while (r >= 10000) { | |
| 191 | − q = r + '0'; | |
| 192 | − r = (r * (uint64_t)0x1999999a) >> 32; | |
| 193 | − *buf++ = q - 10*r; | |
| 194 | − } | |
| 219 | + /* 0 <= r < 10^8 */ | |
| 220 | + q = (r * (u64)0x28f5c29) >> 32; | |
| 221 | + *((u16 *)buf) = decpair[r - 100*q]; | |
| 222 | + buf += 2; | |
| 195 | 223 | |
| 196 | − q = (r * 0x199a) >> 16; /* r <= 9999 */ | |
| 197 | − *buf++ = (r - 10 * q) + '0'; | |
| 198 | − if (q == 0) | |
| 199 | − return buf; | |
| 200 | − r = (q * 0xcd) >> 11; /* q <= 999 */ | |
| 201 | − *buf++ = (q - 10 * r) + '0'; | |
| 202 | − if (r == 0) | |
| 203 | − return buf; | |
| 204 | − q = (r * 0xcd) >> 11; /* r <= 99 */ | |
| 205 | − *buf++ = (r - 10 * q) + '0'; | |
| 206 | − if (q == 0) | |
| 207 | − return buf; | |
| 208 | − *buf++ = q + '0'; /* q <= 9 */ | |
| 209 | − return buf; | |
| 210 | −} | |
| 224 | + /* 0 <= q < 10^6 */ | |
| 225 | + r = (q * (u64)0x28f5c29) >> 32; | |
| 226 | + *((u16 *)buf) = decpair[q - 100*r]; | |
| 227 | + buf += 2; | |
| 211 | 228 | |
| 212 | −/* There are two algorithms to print larger numbers. | |
| 213 | − * One is generic: divide by 1000000000 and repeatedly print | |
| 214 | − * groups of (up to) 9 digits. It's conceptually simple, | |
| 215 | − * but requires a (unsigned long long) / 1000000000 division. | |
| 216 | − * | |
| 217 | − * Second algorithm splits 64-bit unsigned long long into 16-bit chunks, | |
| 218 | − * manipulates them cleverly and generates groups of 4 decimal digits. | |
| 219 | − * It so happens that it does NOT require long long division. | |
| 220 | − * | |
| 221 | − * If long is > 32 bits, division of 64-bit values is relatively easy, | |
| 222 | − * and we will use the first algorithm. | |
| 223 | − * If long long is > 64 bits (strange architecture with VERY large long long), | |
| 224 | − * second algorithm can't be used, and we again use the first one. | |
| 225 | − * | |
| 226 | − * Else (if long is 32 bits and long long is 64 bits) we use second one. | |
| 227 | − */ | |
| 229 | + /* 0 <= r < 10^4 */ | |
| 230 | + q = (r * 0x147b) >> 19; | |
| 231 | + *((u16 *)buf) = decpair[r - 100*q]; | |
| 232 | + buf += 2; | |
| 228 | 233 | |
| 229 | −#if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64 | |
| 230 | − | |
| 231 | −/* First algorithm: generic */ | |
| 234 | + /* 0 <= q < 100 */ | |
| 235 | + *((u16 *)buf) = decpair[q]; | |
| 236 | + buf += 2; | |
| 237 | + return buf; | |
| 238 | +} | |
| 232 | 239 | |
| 233 | −static | |
| 240 | +static noinline_for_stack | |
| 234 | 241 | char *put_dec(char *buf, unsigned long long n) |
| 235 | 242 | { |
| 236 | − if (n >= 100*1000*1000) { | |
| 237 | − while (n >= 1000*1000*1000) | |
| 238 | − buf = put_dec_full9(buf, do_div(n, 1000*1000*1000)); | |
| 239 | − if (n >= 100*1000*1000) | |
| 240 | − return put_dec_full9(buf, n); | |
| 241 | − } | |
| 243 | + if (n >= 100*1000*1000) | |
| 244 | + buf = put_dec_full8(buf, do_div(n, 100*1000*1000)); | |
| 245 | + /* 1 <= n <= 1.6e11 */ | |
| 246 | + if (n >= 100*1000*1000) | |
| 247 | + buf = put_dec_full8(buf, do_div(n, 100*1000*1000)); | |
| 248 | + /* 1 <= n < 1e8 */ | |
| 242 | 249 | return put_dec_trunc8(buf, n); |
| 243 | 250 | } |
| 244 | 251 | |
| 245 | −#else | |
| 252 | +#elif BITS_PER_LONG == 32 && BITS_PER_LONG_LONG == 64 | |
| 246 | 253 | |
| 247 | −/* Second algorithm: valid only for 64-bit long longs */ | |
| 248 | − | |
| 249 | −/* See comment in put_dec_full9 for choice of constants */ | |
| 250 | −static noinline_for_stack | |
| 251 | −void put_dec_full4(char *buf, unsigned q) | |
| 254 | +static void | |
| 255 | +put_dec_full4(char *buf, unsigned r) | |
| 252 | 256 | { |
| 253 | − unsigned r; | |
| 254 | − r = (q * 0xccd) >> 15; | |
| 255 | − buf[0] = (q - 10 * r) + '0'; | |
| 256 | − q = (r * 0xcd) >> 11; | |
| 257 | − buf[1] = (r - 10 * q) + '0'; | |
| 258 | − r = (q * 0xcd) >> 11; | |
| 259 | − buf[2] = (q - 10 * r) + '0'; | |
| 260 | − buf[3] = r + '0'; | |
| 257 | + unsigned q; | |
| 258 | + | |
| 259 | + /* 0 <= r < 10^4 */ | |
| 260 | + q = (r * 0x147b) >> 19; | |
| 261 | + *((u16 *)buf) = decpair[r - 100*q]; | |
| 262 | + buf += 2; | |
| 263 | + /* 0 <= q < 100 */ | |
| 264 | + *((u16 *)buf) = decpair[q]; | |
| 261 | 265 | } |
| 262 | 266 | |
| 263 | 267 | /* |
| @@ -265,9 +269,9 @@ void put_dec_full4(char *buf, unsigned q) · 1 unmodified line | ||
| 265 | 269 | * The approximation x/10000 == (x * 0x346DC5D7) >> 43 |
| 266 | 270 | * holds for all x < 1,128,869,999. The largest value this |
| 267 | 271 | * helper will ever be asked to convert is 1,125,520,955. |
| 268 | − * (d1 in the put_dec code, assuming n is all-ones). | |
| 272 | + * (second call in the put_dec code, assuming n is all-ones). | |
| 269 | 273 | */ |
| 270 | −static | |
| 274 | +static noinline_for_stack | |
| 271 | 275 | unsigned put_dec_helper4(char *buf, unsigned x) |
| 272 | 276 | { |
| 273 | 277 | uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43; |
| @@ -294,6 +298,8 @@ char *put_dec(char *buf, unsigned long long n) · 20 unmodified lines | ||
| 294 | 298 | d2 = (h ) & 0xffff; |
| 295 | 299 | d3 = (h >> 16); /* implicit "& 0xffff" */ |
| 296 | 300 | |
| 301 | + /* n = 2^48 d3 + 2^32 d2 + 2^16 d1 + d0 | |
| 302 | + = 281_4749_7671_0656 d3 + 42_9496_7296 d2 + 6_5536 d1 + d0 */ | |
| 297 | 303 | q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff); |
| 298 | 304 | q = put_dec_helper4(buf, q); |
| 299 | 305 | |
| @@ -323,7 +329,8 @@ char *put_dec(char *buf, unsigned long long n) · 23 unmodified lines | ||
| 323 | 329 | */ |
| 324 | 330 | int num_to_str(char *buf, int size, unsigned long long num) |
| 325 | 331 | { |
| 326 | − char tmp[sizeof(num) * 3]; | |
| 332 | + /* put_dec requires 2-byte alignment of the buffer. */ | |
| 333 | + char tmp[sizeof(num) * 3] __aligned(2); | |
| 327 | 334 | int idx, len; |
| 328 | 335 | |
| 329 | 336 | /* put_dec() may work incorrectly for num = 0 (generate "", not "0") */ |
| @@ -384,7 +391,8 @@ static noinline_for_stack · 54 unmodified lines | ||
| 384 | 391 | char *number(char *buf, char *end, unsigned long long num, |
| 385 | 392 | struct printf_spec spec) |
| 386 | 393 | { |
| 387 | − char tmp[3 * sizeof(num)]; | |
| 394 | + /* put_dec requires 2-byte alignment of the buffer. */ | |
| 395 | + char tmp[3 * sizeof(num)] __aligned(2); | |
| 388 | 396 | char sign; |
| 389 | 397 | char locase; |
| 390 | 398 | int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); |
| @@ -944,7 +952,7 @@ char *ip4_string(char *p, const u8 *addr, const char *fmt) · 553 unmodified lines | ||
| 944 | 952 | break; |
| 945 | 953 | } |
| 946 | 954 | for (i = 0; i < 4; i++) { |
| 947 | − char temp[3]; /* hold each IP quad in reverse order */ | |
| 955 | + char temp[4] __aligned(2); /* hold each IP quad in reverse order */ | |
| 948 | 956 | int digits = put_dec_trunc8(temp, addr[index]) - temp; |
| 949 | 957 | if (leading_zeros) { |
| 950 | 958 | if (digits < 3) |
| @@ -13,12 +13,16 @@ CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \ · 12 unmodified lines | ||
| 13 | 13 | --param asan-instrumentation-with-call-threshold=$(call_threshold)) |
| 14 | 14 | |
| 15 | 15 | ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),) |
| 16 | + ifneq ($(CONFIG_COMPILE_TEST),y) | |
| 16 | 17 | $(warning Cannot use CONFIG_KASAN: \ |
| 17 | 18 | -fsanitize=kernel-address is not supported by compiler) |
| 19 | + endif | |
| 18 | 20 | else |
| 19 | 21 | ifeq ($(CFLAGS_KASAN),) |
| 20 | − $(warning CONFIG_KASAN: compiler does not support all options.\ | |
| 21 | − Trying minimal configuration) | |
| 22 | + ifneq ($(CONFIG_COMPILE_TEST),y) | |
| 23 | + $(warning CONFIG_KASAN: compiler does not support all options.\ | |
| 24 | + Trying minimal configuration) | |
| 25 | + endif | |
| 22 | 26 | CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL) |
| 23 | 27 | endif |
| 24 | 28 | endif |
| @@ -47,6 +47,8 @@ my $ignore_perl_version = 0; · 46 unmodified lines | ||
| 47 | 47 | my $minimum_perl_version = 5.10.0; |
| 48 | 48 | my $min_conf_desc_length = 4; |
| 49 | 49 | my $spelling_file = "$D/spelling.txt"; |
| 50 | +my $codespell = 0; | |
| 51 | +my $codespellfile = "/usr/local/share/codespell/dictionary.txt"; | |
| 50 | 52 | |
| 51 | 53 | sub help { |
| 52 | 54 | my ($exitcode) = @_; |
| @@ -88,6 +90,9 @@ Options: · 35 unmodified lines | ||
| 88 | 90 | file. It's your fault if there's no backup or git |
| 89 | 91 | --ignore-perl-version override checking of perl version. expect |
| 90 | 92 | runtime errors. |
| 93 | + --codespell Use the codespell dictionary for spelling/typos | |
| 94 | + (default:/usr/local/share/codespell/dictionary.txt) | |
| 95 | + --codespellfile Use this codespell dictionary | |
| 91 | 96 | -h, --help, --version display this help and exit |
| 92 | 97 | |
| 93 | 98 | When FILE is - read standard input. |
| @@ -146,6 +151,8 @@ GetOptions( · 52 unmodified lines | ||
| 146 | 151 | 'ignore-perl-version!' => \$ignore_perl_version, |
| 147 | 152 | 'debug=s' => \%debug, |
| 148 | 153 | 'test-only=s' => \$tst_only, |
| 154 | + 'codespell!' => \$codespell, | |
| 155 | + 'codespellfile=s' => \$codespellfile, | |
| 149 | 156 | 'h|help' => \$help, |
| 150 | 157 | 'version' => \$help |
| 151 | 158 | ) or help(1); |
| @@ -316,6 +323,7 @@ our $Operators = qr{ · 164 unmodified lines | ||
| 316 | 323 | |
| 317 | 324 | our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; |
| 318 | 325 | |
| 326 | +our $BasicType; | |
| 319 | 327 | our $NonptrType; |
| 320 | 328 | our $NonptrTypeMisordered; |
| 321 | 329 | our $NonptrTypeWithAttr; |
| @@ -436,6 +444,14 @@ foreach my $entry (@mode_permission_funcs) { · 114 unmodified lines | ||
| 436 | 444 | $mode_perms_search .= $entry->[0]; |
| 437 | 445 | } |
| 438 | 446 | |
| 447 | +our $mode_perms_world_writable = qr{ | |
| 448 | + S_IWUGO | | |
| 449 | + S_IWOTH | | |
| 450 | + S_IRWXUGO | | |
| 451 | + S_IALLUGO | | |
| 452 | + 0[0-7][0-7][2367] | |
| 453 | +}x; | |
| 454 | + | |
| 439 | 455 | our $allowed_asm_includes = qr{(?x: |
| 440 | 456 | irq| |
| 441 | 457 | memory| |
| @@ -449,7 +465,6 @@ my $misspellings; · 7 unmodified lines | ||
| 449 | 465 | my %spelling_fix; |
| 450 | 466 | |
| 451 | 467 | if (open(my $spelling, '<', $spelling_file)) { |
| 452 | − my @spelling_list; | |
| 453 | 468 | while (<$spelling>) { |
| 454 | 469 | my $line = $_; |
| 455 | 470 | |
| @@ -461,21 +476,50 @@ if (open(my $spelling, '<', $spelling_file)) { · 5 unmodified lines | ||
| 461 | 476 | |
| 462 | 477 | my ($suspect, $fix) = split(/\|\|/, $line); |
| 463 | 478 | |
| 464 | − push(@spelling_list, $suspect); | |
| 465 | 479 | $spelling_fix{$suspect} = $fix; |
| 466 | 480 | } |
| 467 | 481 | close($spelling); |
| 468 | − $misspellings = join("|", @spelling_list); | |
| 469 | 482 | } else { |
| 470 | 483 | warn "No typos will be found - file '$spelling_file': $!\n"; |
| 471 | 484 | } |
| 472 | 485 | |
| 486 | +if ($codespell) { | |
| 487 | + if (open(my $spelling, '<', $codespellfile)) { | |
| 488 | + while (<$spelling>) { | |
| 489 | + my $line = $_; | |
| 490 | + | |
| 491 | + $line =~ s/\s*\n?$//g; | |
| 492 | + $line =~ s/^\s*//g; | |
| 493 | + | |
| 494 | + next if ($line =~ m/^\s*#/); | |
| 495 | + next if ($line =~ m/^\s*$/); | |
| 496 | + next if ($line =~ m/, disabled/i); | |
| 497 | + | |
| 498 | + $line =~ s/,.*$//; | |
| 499 | + | |
| 500 | + my ($suspect, $fix) = split(/->/, $line); | |
| 501 | + | |
| 502 | + $spelling_fix{$suspect} = $fix; | |
| 503 | + } | |
| 504 | + close($spelling); | |
| 505 | + } else { | |
| 506 | + warn "No codespell typos will be found - file '$codespellfile': $!\n"; | |
| 507 | + } | |
| 508 | +} | |
| 509 | + | |
| 510 | +$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; | |
| 511 | + | |
| 473 | 512 | sub build_types { |
| 474 | 513 | my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; |
| 475 | 514 | my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; |
| 476 | 515 | my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; |
| 477 | 516 | my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; |
| 478 | 517 | $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; |
| 518 | + $BasicType = qr{ | |
| 519 | + (?:$typeOtherOSTypedefs\b)| | |
| 520 | + (?:$typeTypedefs\b)| | |
| 521 | + (?:${all}\b) | |
| 522 | + }x; | |
| 479 | 523 | $NonptrType = qr{ |
| 480 | 524 | (?:$Modifier\s+|const\s+)* |
| 481 | 525 | (?: |
| @@ -1646,7 +1690,7 @@ sub fix_inserted_deleted_lines { · 1164 unmodified lines | ||
| 1646 | 1690 | foreach my $old_line (@{$linesRef}) { |
| 1647 | 1691 | my $save_line = 1; |
| 1648 | 1692 | my $line = $old_line; #don't modify the array |
| 1649 | − if ($line =~ /^(?:\+\+\+\|\-\-\-)\s+\S+/) { #new filename | |
| 1693 | + if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename | |
| 1650 | 1694 | $delta_offset = 0; |
| 1651 | 1695 | } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk |
| 1652 | 1696 | $range_last_linenr = $new_linenr; |
| @@ -1854,6 +1898,7 @@ sub process { · 201 unmodified lines | ||
| 1854 | 1898 | |
| 1855 | 1899 | my $in_header_lines = $file ? 0 : 1; |
| 1856 | 1900 | my $in_commit_log = 0; #Scanning lines before patch |
| 1901 | + my $commit_log_long_line = 0; | |
| 1857 | 1902 | my $reported_maintainer_file = 0; |
| 1858 | 1903 | my $non_utf8_charset = 0; |
| 1859 | 1904 | |
| @@ -2189,6 +2234,14 @@ sub process { · 329 unmodified lines | ||
| 2189 | 2234 | "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); |
| 2190 | 2235 | } |
| 2191 | 2236 | |
| 2237 | +# Check for line lengths > 75 in commit log, warn once | |
| 2238 | + if ($in_commit_log && !$commit_log_long_line && | |
| 2239 | + length($line) > 75) { | |
| 2240 | + WARN("COMMIT_LOG_LONG_LINE", | |
| 2241 | + "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); | |
| 2242 | + $commit_log_long_line = 1; | |
| 2243 | + } | |
| 2244 | + | |
| 2192 | 2245 | # Check for git id commit length and improperly formed commit descriptions |
| 2193 | 2246 | if ($in_commit_log && $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i) { |
| 2194 | 2247 | my $init_char = $1; |
| @@ -2303,8 +2356,9 @@ sub process { · 108 unmodified lines | ||
| 2303 | 2356 | } |
| 2304 | 2357 | |
| 2305 | 2358 | # Check for various typo / spelling mistakes |
| 2306 | − if (defined($misspellings) && ($in_commit_log || $line =~ /^\+/)) { | |
| 2307 | − while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:$|[^a-z@])/gi) { | |
| 2359 | + if (defined($misspellings) && | |
| 2360 | + ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { | |
| 2361 | + while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { | |
| 2308 | 2362 | my $typo = $1; |
| 2309 | 2363 | my $typo_fix = $spelling_fix{lc($typo)}; |
| 2310 | 2364 | $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); |
| @@ -2459,8 +2513,9 @@ sub process { · 148 unmodified lines | ||
| 2459 | 2513 | #line length limit |
| 2460 | 2514 | if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && |
| 2461 | 2515 | $rawline !~ /^.\s*\*\s*\@$Ident\s/ && |
| 2462 | − !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ || | |
| 2463 | − $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && | |
| 2516 | + !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ || | |
| 2517 | + $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || | |
| 2518 | + $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) && | |
| 2464 | 2519 | $length > $max_line_length) |
| 2465 | 2520 | { |
| 2466 | 2521 | WARN("LONG_LINE", |
| @@ -2552,8 +2607,15 @@ sub process { · 85 unmodified lines | ||
| 2552 | 2607 | } |
| 2553 | 2608 | } |
| 2554 | 2609 | |
| 2555 | − if ($line =~ /^\+.*(\w+\s*)?\(\s*$Type\s*\)[ \t]+(?!$Assignment|$Arithmetic|[,;:\?\(\{\}\[\<\>]|&&|\|\||\\$)/ && | |
| 2556 | − (!defined($1) || $1 !~ /sizeof\s*/)) { | |
| 2610 | +# check for space after cast like "(int) foo" or "(struct foo) bar" | |
| 2611 | +# avoid checking a few false positives: | |
| 2612 | +# "sizeof(<type>)" or "__alignof__(<type>)" | |
| 2613 | +# function pointer declarations like "(*foo)(int) = bar;" | |
| 2614 | +# structure definitions like "(struct foo) { 0 };" | |
| 2615 | +# multiline macros that define functions | |
| 2616 | +# known attributes or the __attribute__ keyword | |
| 2617 | + if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && | |
| 2618 | + (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { | |
| 2557 | 2619 | if (CHK("SPACING", |
| 2558 | 2620 | "No space is necessary after a cast\n" . $herecurr) && |
| 2559 | 2621 | $fix) { |
| @@ -3146,6 +3208,18 @@ sub process { · 586 unmodified lines | ||
| 3146 | 3208 | $herecurr); |
| 3147 | 3209 | } |
| 3148 | 3210 | |
| 3211 | +# check for const <foo> const where <foo> is not a pointer or array type | |
| 3212 | + if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { | |
| 3213 | + my $found = $1; | |
| 3214 | + if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { | |
| 3215 | + WARN("CONST_CONST", | |
| 3216 | + "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); | |
| 3217 | + } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { | |
| 3218 | + WARN("CONST_CONST", | |
| 3219 | + "'const $found const' should probably be 'const $found'\n" . $herecurr); | |
| 3220 | + } | |
| 3221 | + } | |
| 3222 | + | |
| 3149 | 3223 | # check for non-global char *foo[] = {"bar", ...} declarations. |
| 3150 | 3224 | if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { |
| 3151 | 3225 | WARN("STATIC_CONST_CHAR_ARRAY", |
| @@ -3153,6 +3227,19 @@ sub process { · 1 unmodified line | ||
| 3153 | 3227 | $herecurr); |
| 3154 | 3228 | } |
| 3155 | 3229 | |
| 3230 | +# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) | |
| 3231 | + if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { | |
| 3232 | + my $array = $1; | |
| 3233 | + if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { | |
| 3234 | + my $array_div = $1; | |
| 3235 | + if (WARN("ARRAY_SIZE", | |
| 3236 | + "Prefer ARRAY_SIZE($array)\n" . $herecurr) && | |
| 3237 | + $fix) { | |
| 3238 | + $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; | |
| 3239 | + } | |
| 3240 | + } | |
| 3241 | + } | |
| 3242 | + | |
| 3156 | 3243 | # check for function declarations without arguments like "int foo()" |
| 3157 | 3244 | if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { |
| 3158 | 3245 | if (ERROR("FUNCTION_WITHOUT_ARGS", |
| @@ -3309,6 +3396,14 @@ sub process { · 150 unmodified lines | ||
| 3309 | 3396 | "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); |
| 3310 | 3397 | } |
| 3311 | 3398 | |
| 3399 | +# ENOSYS means "bad syscall nr" and nothing else. This will have a small | |
| 3400 | +# number of false positives, but assembly files are not checked, so at | |
| 3401 | +# least the arch entry code will not trigger this warning. | |
| 3402 | + if ($line =~ /\bENOSYS\b/) { | |
| 3403 | + WARN("ENOSYS", | |
| 3404 | + "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); | |
| 3405 | + } | |
| 3406 | + | |
| 3312 | 3407 | # function brace can't be on same line, except for #defines of do while, |
| 3313 | 3408 | # or if closed on same line |
| 3314 | 3409 | if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and |
| @@ -3565,7 +3660,7 @@ sub process { · 250 unmodified lines | ||
| 3565 | 3660 | |
| 3566 | 3661 | # Ignore operators passed as parameters. |
| 3567 | 3662 | if ($op_type ne 'V' && |
| 3568 | − $ca =~ /\s$/ && $cc =~ /^\s*,/) { | |
| 3663 | + $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { | |
| 3569 | 3664 | |
| 3570 | 3665 | # # Ignore comments |
| 3571 | 3666 | # } elsif ($op =~ /^$;+$/) { |
| @@ -3750,6 +3845,14 @@ sub process { · 178 unmodified lines | ||
| 3750 | 3845 | $ok = 1; |
| 3751 | 3846 | } |
| 3752 | 3847 | |
| 3848 | + # for asm volatile statements | |
| 3849 | + # ignore a colon with another | |
| 3850 | + # colon immediately before or after | |
| 3851 | + if (($op eq ':') && | |
| 3852 | + ($ca =~ /:$/ || $cc =~ /^:/)) { | |
| 3853 | + $ok = 1; | |
| 3854 | + } | |
| 3855 | + | |
| 3753 | 3856 | # messages are ERROR, but ?: are CHK |
| 3754 | 3857 | if ($ok == 0) { |
| 3755 | 3858 | my $msg_type = \&ERROR; |
| @@ -3963,12 +4066,12 @@ sub process { · 207 unmodified lines | ||
| 3963 | 4066 | } |
| 3964 | 4067 | } |
| 3965 | 4068 | |
| 3966 | −# Return of what appears to be an errno should normally be -'ve | |
| 3967 | − if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { | |
| 4069 | +# Return of what appears to be an errno should normally be negative | |
| 4070 | + if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { | |
| 3968 | 4071 | my $name = $1; |
| 3969 | 4072 | if ($name ne 'EOF' && $name ne 'ERROR') { |
| 3970 | 4073 | WARN("USE_NEGATIVE_ERRNO", |
| 3971 | − "return of an errno should typically be -ve (return -$1)\n" . $herecurr); | |
| 4074 | + "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); | |
| 3972 | 4075 | } |
| 3973 | 4076 | } |
| 3974 | 4077 | |
| @@ -4178,7 +4281,8 @@ sub process { · 203 unmodified lines | ||
| 4178 | 4281 | } |
| 4179 | 4282 | } |
| 4180 | 4283 | |
| 4181 | −#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) | |
| 4284 | +# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes | |
| 4285 | +# itself <asm/foo.h> (uses RAW line) | |
| 4182 | 4286 | if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { |
| 4183 | 4287 | my $file = "$1.h"; |
| 4184 | 4288 | my $checkfile = "include/linux/$file"; |
| @@ -4186,12 +4290,15 @@ sub process { · 1 unmodified line | ||
| 4186 | 4290 | $realfile ne $checkfile && |
| 4187 | 4291 | $1 !~ /$allowed_asm_includes/) |
| 4188 | 4292 | { |
| 4189 | − if ($realfile =~ m{^arch/}) { | |
| 4190 | − CHK("ARCH_INCLUDE_LINUX", | |
| 4191 | − "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); | |
| 4192 | − } else { | |
| 4193 | − WARN("INCLUDE_LINUX", | |
| 4194 | − "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); | |
| 4293 | + my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; | |
| 4294 | + if ($asminclude > 0) { | |
| 4295 | + if ($realfile =~ m{^arch/}) { | |
| 4296 | + CHK("ARCH_INCLUDE_LINUX", | |
| 4297 | + "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); | |
| 4298 | + } else { | |
| 4299 | + WARN("INCLUDE_LINUX", | |
| 4300 | + "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); | |
| 4301 | + } | |
| 4195 | 4302 | } |
| 4196 | 4303 | } |
| 4197 | 4304 | } |
| @@ -4700,6 +4807,16 @@ sub process { · 502 unmodified lines | ||
| 4700 | 4807 | } |
| 4701 | 4808 | } |
| 4702 | 4809 | |
| 4810 | +# check for __read_mostly with const non-pointer (should just be const) | |
| 4811 | + if ($line =~ /\b__read_mostly\b/ && | |
| 4812 | + $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { | |
| 4813 | + if (ERROR("CONST_READ_MOSTLY", | |
| 4814 | + "Invalid use of __read_mostly with const type\n" . $herecurr) && | |
| 4815 | + $fix) { | |
| 4816 | + $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; | |
| 4817 | + } | |
| 4818 | + } | |
| 4819 | + | |
| 4703 | 4820 | # don't use __constant_<foo> functions outside of include/uapi/ |
| 4704 | 4821 | if ($realfile !~ m@^include/uapi/@ && |
| 4705 | 4822 | $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { |
| @@ -5261,6 +5378,7 @@ sub process { · 555 unmodified lines | ||
| 5261 | 5378 | stacktrace_ops| |
| 5262 | 5379 | sysfs_ops| |
| 5263 | 5380 | tty_operations| |
| 5381 | + uart_ops| | |
| 5264 | 5382 | usb_mon_operations| |
| 5265 | 5383 | wd_ops}x; |
| 5266 | 5384 | if ($line !~ /\bconst\b/ && |
| @@ -5318,8 +5436,8 @@ sub process { · 51 unmodified lines | ||
| 5318 | 5436 | } |
| 5319 | 5437 | } |
| 5320 | 5438 | |
| 5321 | − if ($line =~ /debugfs_create_file.*S_IWUGO/ || | |
| 5322 | − $line =~ /DEVICE_ATTR.*S_IWUGO/ ) { | |
| 5439 | + if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || | |
| 5440 | + $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { | |
| 5323 | 5441 | WARN("EXPORTED_WORLD_WRITABLE", |
| 5324 | 5442 | "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); |
| 5325 | 5443 | } |
| @@ -825,6 +825,7 @@ retreived||retrieved · 824 unmodified lines | ||
| 825 | 825 | retreive||retrieve |
| 826 | 826 | retrive||retrieve |
| 827 | 827 | retuned||returned |
| 828 | +reudce||reduce | |
| 828 | 829 | reuest||request |
| 829 | 830 | reuqest||request |
| 830 | 831 | reutnred||returned |
| @@ -948,15 +948,18 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, · 947 unmodified lines | ||
| 948 | 948 | */ |
| 949 | 949 | const char *tomoyo_get_exe(void) |
| 950 | 950 | { |
| 951 | + struct file *exe_file; | |
| 952 | + const char *cp; | |
| 951 | 953 | struct mm_struct *mm = current->mm; |
| 952 | − const char *cp = NULL; | |
| 953 | 954 | |
| 954 | 955 | if (!mm) |
| 955 | 956 | return NULL; |
| 956 | − down_read(&mm->mmap_sem); | |
| 957 | − if (mm->exe_file) | |
| 958 | − cp = tomoyo_realpath_from_path(&mm->exe_file->f_path); | |
| 959 | − up_read(&mm->mmap_sem); | |
| 957 | + exe_file = get_mm_exe_file(mm); | |
| 958 | + if (!exe_file) | |
| 959 | + return NULL; | |
| 960 | + | |
| 961 | + cp = tomoyo_realpath_from_path(&exe_file->f_path); | |
| 962 | + fput(exe_file); | |
| 960 | 963 | return cp; |
| 961 | 964 | } |
| 962 | 965 | |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/init.h> |
| 19 | 19 | #include <linux/module.h> |
| 20 | 20 | #include <linux/clk.h> |
| 21 | +#include <linux/kernel.h> | |
| 21 | 22 | #include <linux/pm_runtime.h> |
| 22 | 23 | #include <linux/regmap.h> |
| 23 | 24 | #include <linux/regulator/consumer.h> |
| @@ -31,8 +32,6 @@ · 7 unmodified lines | ||
| 31 | 32 | |
| 32 | 33 | #define DIV_ROUND_DOWN_ULL(ll, d) \ |
| 33 | 34 | ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) |
| 34 | −#define DIV_ROUND_CLOSEST_ULL(ll, d) \ | |
| 35 | − ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | |
| 36 | 35 | |
| 37 | 36 | #define PCM512x_NUM_SUPPLIES 3 |
| 38 | 37 | static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { |