mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-15 21:30:43 +00:00
Merge branch 'akpm' (patches from Andrew Morton) into next
Merge more updates from Andrew Morton: - Most of the rest of MM. This includes "mark remap_file_pages syscall as deprecated" but the actual "replace remap_file_pages syscall with emulation" is held back. I guess we'll need to work out when to pull the trigger on that one. - various minor cleanups to obscure filesystems - the drivers/rtc queue - hfsplus updates - ufs, hpfs, fatfs, affs, reiserfs - Documentation/ - signals - procfs - cpu hotplug - lib/idr.c - rapidio - sysctl - ipc updates * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (171 commits) ufs: sb mutex merge + mutex_destroy powerpc: update comments for generic idle conversion cris: update comments for generic idle conversion idle: remove cpu_idle() forward declarations nbd: zero from and len fields in NBD_CMD_DISCONNECT. mm: convert some level-less printks to pr_* MAINTAINERS: adi-buildroot-devel is moderated MAINTAINERS: add linux-api for review of API/ABI changes mm/kmemleak-test.c: use pr_fmt for logging fs/dlm/debug_fs.c: replace seq_printf by seq_puts fs/dlm/lockspace.c: convert simple_str to kstr fs/dlm/config.c: convert simple_str to kstr mm: mark remap_file_pages() syscall as deprecated mm: memcontrol: remove unnecessary memcg argument from soft limit functions mm: memcontrol: clean up memcg zoneinfo lookup mm/memblock.c: call kmemleak directly from memblock_(alloc|free) mm/mempool.c: update the kmemleak stack trace for mempool allocations lib/radix-tree.c: update the kmemleak stack trace for radix tree allocations mm: introduce kmemleak_update_trace() mm/kmemleak.c: use %u to print ->checksum ...
This commit is contained in:
commit
57d326169e
@ -132,6 +132,20 @@ Example:
|
||||
platform_set_drvdata(), but left the variable "dev" unused,
|
||||
delete it.
|
||||
|
||||
If your patch fixes a bug in a specific commit, e.g. you found an issue using
|
||||
git-bisect, please use the 'Fixes:' tag with the first 12 characters of the
|
||||
SHA-1 ID, and the one line summary.
|
||||
Example:
|
||||
|
||||
Fixes: e21d2170f366 ("video: remove unnecessary platform_set_drvdata()")
|
||||
|
||||
The following git-config settings can be used to add a pretty format for
|
||||
outputting the above style in the git log or git show commands
|
||||
|
||||
[core]
|
||||
abbrev = 12
|
||||
[pretty]
|
||||
fixes = Fixes: %h (\"%s\")
|
||||
|
||||
3) Separate your changes.
|
||||
|
||||
@ -443,7 +457,7 @@ person it names. This tag documents that potentially interested parties
|
||||
have been included in the discussion
|
||||
|
||||
|
||||
14) Using Reported-by:, Tested-by:, Reviewed-by: and Suggested-by:
|
||||
14) Using Reported-by:, Tested-by:, Reviewed-by:, Suggested-by: and Fixes:
|
||||
|
||||
If this patch fixes a problem reported by somebody else, consider adding a
|
||||
Reported-by: tag to credit the reporter for their contribution. Please
|
||||
@ -498,6 +512,12 @@ idea was not posted in a public forum. That said, if we diligently credit our
|
||||
idea reporters, they will, hopefully, be inspired to help us again in the
|
||||
future.
|
||||
|
||||
A Fixes: tag indicates that the patch fixes an issue in a previous commit. It
|
||||
is used to make it easy to determine where a bug originated, which can help
|
||||
review a bug fix. This tag also assists the stable kernel team in determining
|
||||
which stable kernel versions should receive your fix. This is the preferred
|
||||
method for indicating a bug fixed by the patch. See #2 above for more details.
|
||||
|
||||
|
||||
15) The canonical patch format
|
||||
|
||||
|
@ -540,14 +540,13 @@ Note:
|
||||
|
||||
5.3 swappiness
|
||||
|
||||
Similar to /proc/sys/vm/swappiness, but only affecting reclaim that is
|
||||
triggered by this cgroup's hard limit. The tunable in the root cgroup
|
||||
corresponds to the global swappiness setting.
|
||||
Overrides /proc/sys/vm/swappiness for the particular group. The tunable
|
||||
in the root cgroup corresponds to the global swappiness setting.
|
||||
|
||||
Please note that unlike the global swappiness, memcg knob set to 0
|
||||
really prevents from any swapping even if there is a swap storage
|
||||
available. This might lead to memcg OOM killer if there are no file
|
||||
pages to reclaim.
|
||||
Please note that unlike during the global reclaim, limit reclaim
|
||||
enforces that 0 swappiness really prevents from any swapping even if
|
||||
there is a swap storage available. This might lead to memcg OOM killer
|
||||
if there are no file pages to reclaim.
|
||||
|
||||
5.4 failcnt
|
||||
|
||||
|
@ -9,6 +9,9 @@ Required properties:
|
||||
- interrupts: rtc alarm/event interrupt
|
||||
- #clock-cells: the value should be 0
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names: From common clock binding
|
||||
|
||||
Example:
|
||||
|
||||
hym8563: hym8563@51 {
|
||||
|
28
Documentation/devicetree/bindings/rtc/xgene-rtc.txt
Normal file
28
Documentation/devicetree/bindings/rtc/xgene-rtc.txt
Normal file
@ -0,0 +1,28 @@
|
||||
* APM X-Gene Real Time Clock
|
||||
|
||||
RTC controller for the APM X-Gene Real Time Clock
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "apm,xgene-rtc"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- interrupts: IRQ line for the RTC.
|
||||
- #clock-cells: Should be 1.
|
||||
- clocks: Reference to the clock entry.
|
||||
|
||||
Example:
|
||||
|
||||
rtcclk: rtcclk {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <1>;
|
||||
clock-frequency = <100000000>;
|
||||
clock-output-names = "rtcclk";
|
||||
};
|
||||
|
||||
rtc: rtc@10510000 {
|
||||
compatible = "apm,xgene-rtc";
|
||||
reg = <0x0 0x10510000 0x0 0x400>;
|
||||
interrupts = <0x0 0x46 0x4>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&rtcclk 0>;
|
||||
};
|
@ -54,6 +54,15 @@ how the mechanism works without getting lost in other details. (Those
|
||||
wanting to see the full source for this module can find it at
|
||||
http://lwn.net/Articles/22359/).
|
||||
|
||||
Deprecated create_proc_entry
|
||||
|
||||
Note that the above article uses create_proc_entry which was removed in
|
||||
kernel 3.10. Current versions require the following update
|
||||
|
||||
- entry = create_proc_entry("sequence", 0, NULL);
|
||||
- if (entry)
|
||||
- entry->proc_fops = &ct_file_ops;
|
||||
+ entry = proc_create("sequence", 0, NULL, &ct_file_ops);
|
||||
|
||||
The iterator interface
|
||||
|
||||
|
@ -172,6 +172,11 @@ nfs=stale_rw|nostale_ro
|
||||
To maintain backward compatibility, '-o nfs' is also accepted,
|
||||
defaulting to stale_rw
|
||||
|
||||
dos1xfloppy -- If set, use a fallback default BIOS Parameter Block
|
||||
configuration, determined by backing device size. These static
|
||||
parameters match defaults assumed by DOS 1.x for 160 kiB,
|
||||
180 kiB, 320 kiB, and 360 kiB floppies and floppy images.
|
||||
|
||||
|
||||
<bool>: 0,1,yes,no,true,false
|
||||
|
||||
|
@ -2361,6 +2361,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
timeout < 0: reboot immediately
|
||||
Format: <timeout>
|
||||
|
||||
crash_kexec_post_notifiers
|
||||
Run kdump after running panic-notifiers and dumping
|
||||
kmsg. This only for the users who doubt kdump always
|
||||
succeeds in any situation.
|
||||
Note that this also increases risks of kdump failure,
|
||||
because some panic notifiers can make the crashed
|
||||
kernel more unstable.
|
||||
|
||||
parkbd.port= [HW] Parallel port number the keyboard adapter is
|
||||
connected to, default is 0.
|
||||
Format: <parport#>
|
||||
|
@ -142,6 +142,7 @@ kmemleak_alloc_percpu - notify of a percpu memory block allocation
|
||||
kmemleak_free - notify of a memory block freeing
|
||||
kmemleak_free_part - notify of a partial memory block freeing
|
||||
kmemleak_free_percpu - notify of a percpu memory block freeing
|
||||
kmemleak_update_trace - update object allocation stack trace
|
||||
kmemleak_not_leak - mark an object as not a leak
|
||||
kmemleak_ignore - do not scan or report an object as leak
|
||||
kmemleak_scan_area - add scan areas inside a memory block
|
||||
|
@ -115,8 +115,8 @@ For example, consider the following sequence of events:
|
||||
CPU 1 CPU 2
|
||||
=============== ===============
|
||||
{ A == 1; B == 2 }
|
||||
A = 3; x = A;
|
||||
B = 4; y = B;
|
||||
A = 3; x = B;
|
||||
B = 4; y = A;
|
||||
|
||||
The set of accesses as seen by the memory system in the middle can be arranged
|
||||
in 24 different combinations:
|
||||
|
@ -77,6 +77,7 @@ show up in /proc/sys/kernel:
|
||||
- shmmni
|
||||
- stop-a [ SPARC only ]
|
||||
- sysrq ==> Documentation/sysrq.txt
|
||||
- sysctl_writes_strict
|
||||
- tainted
|
||||
- threads-max
|
||||
- unknown_nmi_panic
|
||||
@ -762,6 +763,26 @@ without users and with a dead originative process will be destroyed.
|
||||
|
||||
==============================================================
|
||||
|
||||
sysctl_writes_strict:
|
||||
|
||||
Control how file position affects the behavior of updating sysctl values
|
||||
via the /proc/sys interface:
|
||||
|
||||
-1 - Legacy per-write sysctl value handling, with no printk warnings.
|
||||
Each write syscall must fully contain the sysctl value to be
|
||||
written, and multiple writes on the same sysctl file descriptor
|
||||
will rewrite the sysctl value, regardless of file position.
|
||||
0 - (default) Same behavior as above, but warn about processes that
|
||||
perform writes to a sysctl file descriptor when the file position
|
||||
is not 0.
|
||||
1 - Respect file position when writing sysctl strings. Multiple writes
|
||||
will append to the sysctl value buffer. Anything past the max length
|
||||
of the sysctl value buffer will be ignored. Writes to numeric sysctl
|
||||
entries must always be at file position 0 and the value must be
|
||||
fully contained in the buffer sent in the write syscall.
|
||||
|
||||
==============================================================
|
||||
|
||||
tainted:
|
||||
|
||||
Non-zero if the kernel has been tainted. Numeric values, which
|
||||
|
28
Documentation/vm/remap_file_pages.txt
Normal file
28
Documentation/vm/remap_file_pages.txt
Normal file
@ -0,0 +1,28 @@
|
||||
The remap_file_pages() system call is used to create a nonlinear mapping,
|
||||
that is, a mapping in which the pages of the file are mapped into a
|
||||
nonsequential order in memory. The advantage of using remap_file_pages()
|
||||
over using repeated calls to mmap(2) is that the former approach does not
|
||||
require the kernel to create additional VMA (Virtual Memory Area) data
|
||||
structures.
|
||||
|
||||
Supporting of nonlinear mapping requires significant amount of non-trivial
|
||||
code in kernel virtual memory subsystem including hot paths. Also to get
|
||||
nonlinear mapping work kernel need a way to distinguish normal page table
|
||||
entries from entries with file offset (pte_file). Kernel reserves flag in
|
||||
PTE for this purpose. PTE flags are scarce resource especially on some CPU
|
||||
architectures. It would be nice to free up the flag for other usage.
|
||||
|
||||
Fortunately, there are not many users of remap_file_pages() in the wild.
|
||||
It's only known that one enterprise RDBMS implementation uses the syscall
|
||||
on 32-bit systems to map files bigger than can linearly fit into 32-bit
|
||||
virtual address space. This use-case is not critical anymore since 64-bit
|
||||
systems are widely available.
|
||||
|
||||
The plan is to deprecate the syscall and replace it with an emulation.
|
||||
The emulation will create new VMAs instead of nonlinear mappings. It's
|
||||
going to work slower for rare users of remap_file_pages() but ABI is
|
||||
preserved.
|
||||
|
||||
One side effect of emulation (apart from performance) is that user can hit
|
||||
vm.max_map_count limit more easily due to additional VMAs. See comment for
|
||||
DEFAULT_MAX_MAP_COUNT for more details on the limit.
|
25
MAINTAINERS
25
MAINTAINERS
@ -210,6 +210,13 @@ S: Supported
|
||||
F: Documentation/scsi/aacraid.txt
|
||||
F: drivers/scsi/aacraid/
|
||||
|
||||
ABI/API
|
||||
L: linux-api@vger.kernel.org
|
||||
F: Documentation/ABI/
|
||||
F: include/linux/syscalls.h
|
||||
F: include/uapi/
|
||||
F: kernel/sys_ni.c
|
||||
|
||||
ABIT UGURU 1,2 HARDWARE MONITOR DRIVER
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
L: lm-sensors@lm-sensors.org
|
||||
@ -647,7 +654,7 @@ F: sound/soc/codecs/ssm*
|
||||
F: sound/soc/codecs/sigmadsp.*
|
||||
|
||||
ANALOG DEVICES INC ASOC DRIVERS
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
W: http://blackfin.uclinux.org/
|
||||
S: Supported
|
||||
@ -1758,54 +1765,54 @@ F: include/uapi/linux/bfs_fs.h
|
||||
|
||||
BLACKFIN ARCHITECTURE
|
||||
M: Steven Miao <realmz6@gmail.com>
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
T: git git://git.code.sf.net/p/adi-linux/code
|
||||
W: http://blackfin.uclinux.org
|
||||
S: Supported
|
||||
F: arch/blackfin/
|
||||
|
||||
BLACKFIN EMAC DRIVER
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: http://blackfin.uclinux.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/adi/
|
||||
|
||||
BLACKFIN RTC DRIVER
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: http://blackfin.uclinux.org
|
||||
S: Supported
|
||||
F: drivers/rtc/rtc-bfin.c
|
||||
|
||||
BLACKFIN SDH DRIVER
|
||||
M: Sonic Zhang <sonic.zhang@analog.com>
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: http://blackfin.uclinux.org
|
||||
S: Supported
|
||||
F: drivers/mmc/host/bfin_sdh.c
|
||||
|
||||
BLACKFIN SERIAL DRIVER
|
||||
M: Sonic Zhang <sonic.zhang@analog.com>
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: http://blackfin.uclinux.org
|
||||
S: Supported
|
||||
F: drivers/tty/serial/bfin_uart.c
|
||||
|
||||
BLACKFIN WATCHDOG DRIVER
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: http://blackfin.uclinux.org
|
||||
S: Supported
|
||||
F: drivers/watchdog/bfin_wdt.c
|
||||
|
||||
BLACKFIN I2C TWI DRIVER
|
||||
M: Sonic Zhang <sonic.zhang@analog.com>
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: http://blackfin.uclinux.org/
|
||||
S: Supported
|
||||
F: drivers/i2c/busses/i2c-bfin-twi.c
|
||||
|
||||
BLACKFIN MEDIA DRIVER
|
||||
M: Scott Jiang <scott.jiang.linux@gmail.com>
|
||||
L: adi-buildroot-devel@lists.sourceforge.net
|
||||
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: http://blackfin.uclinux.org/
|
||||
S: Supported
|
||||
F: drivers/media/platform/blackfin/
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
static unsigned int isa_membase, isa_portbase, isa_portshift;
|
||||
|
||||
static ctl_table ctl_isa_vars[4] = {
|
||||
static struct ctl_table ctl_isa_vars[4] = {
|
||||
{
|
||||
.procname = "membase",
|
||||
.data = &isa_membase,
|
||||
@ -44,7 +44,7 @@ static ctl_table ctl_isa_vars[4] = {
|
||||
|
||||
static struct ctl_table_header *isa_sysctl_header;
|
||||
|
||||
static ctl_table ctl_isa[2] = {
|
||||
static struct ctl_table ctl_isa[2] = {
|
||||
{
|
||||
.procname = "isa",
|
||||
.mode = 0555,
|
||||
@ -52,7 +52,7 @@ static ctl_table ctl_isa[2] = {
|
||||
}, {}
|
||||
};
|
||||
|
||||
static ctl_table ctl_bus[2] = {
|
||||
static struct ctl_table ctl_bus[2] = {
|
||||
{
|
||||
.procname = "bus",
|
||||
.mode = 0555,
|
||||
|
@ -25,24 +25,28 @@
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
|
||||
#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
|
||||
#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
|
||||
#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
|
||||
#define AT91_RTC_IRQ_MASK 0x1f /* Available IRQs mask */
|
||||
|
||||
void __init at91_sysirq_mask_rtc(u32 rtc_base)
|
||||
{
|
||||
void __iomem *base;
|
||||
u32 mask;
|
||||
|
||||
base = ioremap(rtc_base, 64);
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
mask = readl_relaxed(base + AT91_RTC_IMR);
|
||||
if (mask) {
|
||||
pr_info("AT91: Disabling rtc irq\n");
|
||||
writel_relaxed(mask, base + AT91_RTC_IDR);
|
||||
(void)readl_relaxed(base + AT91_RTC_IMR); /* flush */
|
||||
}
|
||||
/*
|
||||
* sam9x5 SoCs have the following errata:
|
||||
* "RTC: Interrupt Mask Register cannot be used
|
||||
* Interrupt Mask Register read always returns 0."
|
||||
*
|
||||
* Hence we're not relying on IMR values to disable
|
||||
* interrupts.
|
||||
*/
|
||||
writel_relaxed(AT91_RTC_IRQ_MASK, base + AT91_RTC_IDR);
|
||||
(void)readl_relaxed(base + AT91_RTC_IMR); /* flush */
|
||||
|
||||
iounmap(base);
|
||||
}
|
||||
|
@ -257,6 +257,19 @@
|
||||
enable-offset = <0x0>;
|
||||
enable-mask = <0x39>;
|
||||
};
|
||||
|
||||
rtcclk: rtcclk@17000000 {
|
||||
compatible = "apm,xgene-device-clock";
|
||||
#clock-cells = <1>;
|
||||
clocks = <&socplldiv2 0>;
|
||||
reg = <0x0 0x17000000 0x0 0x2000>;
|
||||
reg-names = "csr-reg";
|
||||
csr-offset = <0xc>;
|
||||
csr-mask = <0x2>;
|
||||
enable-offset = <0x10>;
|
||||
enable-mask = <0x2>;
|
||||
clock-output-names = "rtcclk";
|
||||
};
|
||||
};
|
||||
|
||||
serial0: serial@1c020000 {
|
||||
@ -342,5 +355,13 @@
|
||||
phys = <&phy3 0>;
|
||||
phy-names = "sata-phy";
|
||||
};
|
||||
|
||||
rtc: rtc@10510000 {
|
||||
compatible = "apm,xgene-rtc";
|
||||
reg = <0x0 0x10510000 0x0 0x400>;
|
||||
interrupts = <0x0 0x46 0x4>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&rtcclk 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -117,6 +117,7 @@ put_reg(struct task_struct *task, unsigned long regno, unsigned long data)
|
||||
int
|
||||
is_user_addr_valid(struct task_struct *child, unsigned long start, unsigned long len)
|
||||
{
|
||||
bool valid;
|
||||
struct vm_area_struct *vma;
|
||||
struct sram_list_struct *sraml;
|
||||
|
||||
@ -124,9 +125,12 @@ is_user_addr_valid(struct task_struct *child, unsigned long start, unsigned long
|
||||
if (start + len < start)
|
||||
return -EIO;
|
||||
|
||||
down_read(&child->mm->mmap_sem);
|
||||
vma = find_vma(child->mm, start);
|
||||
if (vma && start >= vma->vm_start && start + len <= vma->vm_end)
|
||||
return 0;
|
||||
valid = vma && start >= vma->vm_start && start + len <= vma->vm_end;
|
||||
up_read(&child->mm->mmap_sem);
|
||||
if (valid)
|
||||
return 0;
|
||||
|
||||
for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next)
|
||||
if (start >= (unsigned long)sraml->addr
|
||||
|
@ -833,8 +833,8 @@ static int __init gpio_init(void)
|
||||
printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001-2008 "
|
||||
"Axis Communications AB\n");
|
||||
/* We call etrax_gpio_wake_up_check() from timer interrupt and
|
||||
* from cpu_idle() in kernel/process.c
|
||||
* The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
|
||||
* from default_idle() in kernel/process.c
|
||||
* The check in default_idle() reduces latency from ~15 ms to ~6 ms
|
||||
* in some tests.
|
||||
*/
|
||||
res = request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
|
||||
|
@ -958,11 +958,7 @@ gpio_init(void)
|
||||
|
||||
printk(KERN_INFO "ETRAX FS GPIO driver v2.5, (c) 2003-2007 "
|
||||
"Axis Communications AB\n");
|
||||
/* We call etrax_gpio_wake_up_check() from timer interrupt and
|
||||
* from cpu_idle() in kernel/process.c
|
||||
* The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
|
||||
* in some tests.
|
||||
*/
|
||||
/* We call etrax_gpio_wake_up_check() from timer interrupt */
|
||||
if (request_irq(TIMER0_INTR_VECT, gpio_poll_timer_interrupt,
|
||||
IRQF_SHARED, "gpio poll", &alarmlist))
|
||||
printk(KERN_ERR "timer0 irq for gpio\n");
|
||||
|
@ -237,7 +237,7 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static ctl_table kdump_ctl_table[] = {
|
||||
static struct ctl_table kdump_ctl_table[] = {
|
||||
{
|
||||
.procname = "kdump_on_init",
|
||||
.data = &kdump_on_init,
|
||||
@ -255,7 +255,7 @@ static ctl_table kdump_ctl_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static ctl_table sys_table[] = {
|
||||
static struct ctl_table sys_table[] = {
|
||||
{
|
||||
.procname = "kernel",
|
||||
.mode = 0555,
|
||||
|
@ -521,7 +521,7 @@ static pmu_config_t *pmu_conf;
|
||||
pfm_sysctl_t pfm_sysctl;
|
||||
EXPORT_SYMBOL(pfm_sysctl);
|
||||
|
||||
static ctl_table pfm_ctl_table[]={
|
||||
static struct ctl_table pfm_ctl_table[] = {
|
||||
{
|
||||
.procname = "debug",
|
||||
.data = &pfm_sysctl.debug,
|
||||
@ -552,7 +552,7 @@ static ctl_table pfm_ctl_table[]={
|
||||
},
|
||||
{}
|
||||
};
|
||||
static ctl_table pfm_sysctl_dir[] = {
|
||||
static struct ctl_table pfm_sysctl_dir[] = {
|
||||
{
|
||||
.procname = "perfmon",
|
||||
.mode = 0555,
|
||||
@ -560,7 +560,7 @@ static ctl_table pfm_sysctl_dir[] = {
|
||||
},
|
||||
{}
|
||||
};
|
||||
static ctl_table pfm_sysctl_root[] = {
|
||||
static struct ctl_table pfm_sysctl_root[] = {
|
||||
{
|
||||
.procname = "kernel",
|
||||
.mode = 0555,
|
||||
|
@ -60,15 +60,6 @@ static inline int __gen_sigismember(sigset_t *set, int _sig)
|
||||
__const_sigismember(set,sig) : \
|
||||
__gen_sigismember(set,sig))
|
||||
|
||||
static inline int sigfindinword(unsigned long word)
|
||||
{
|
||||
asm ("bfffo %1{#0,#0},%0"
|
||||
: "=d" (word)
|
||||
: "d" (word & -word)
|
||||
: "cc");
|
||||
return word ^ 31;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_CPU_HAS_NO_BITFIELDS */
|
||||
|
||||
#ifndef __uClinux__
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
|
||||
kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
|
||||
kn02-irq.o kn02xa-berr.o platform.o reset.o setup.o time.o
|
||||
|
||||
obj-$(CONFIG_TC) += tc.o
|
||||
obj-$(CONFIG_CPU_HAS_WB) += wbflush.o
|
||||
|
44
arch/mips/dec/platform.c
Normal file
44
arch/mips/dec/platform.c
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* DEC platform devices.
|
||||
*
|
||||
* Copyright (c) 2014 Maciej W. Rozycki
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mc146818rtc.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
static struct resource dec_rtc_resources[] = {
|
||||
{
|
||||
.name = "rtc",
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cmos_rtc_board_info dec_rtc_info = {
|
||||
.flags = CMOS_RTC_FLAGS_NOFREQ,
|
||||
.address_space = 64,
|
||||
};
|
||||
|
||||
static struct platform_device dec_rtc_device = {
|
||||
.name = "rtc_cmos",
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
.dev.platform_data = &dec_rtc_info,
|
||||
.resource = dec_rtc_resources,
|
||||
.num_resources = ARRAY_SIZE(dec_rtc_resources),
|
||||
};
|
||||
|
||||
static int __init dec_add_devices(void)
|
||||
{
|
||||
dec_rtc_resources[0].start = RTC_PORT(0);
|
||||
dec_rtc_resources[0].end = RTC_PORT(0) + dec_kn_slot_size - 1;
|
||||
return platform_device_register(&dec_rtc_device);
|
||||
}
|
||||
|
||||
device_initcall(dec_add_devices);
|
@ -304,7 +304,7 @@ void notrace restore_interrupts(void)
|
||||
* being re-enabled and generally sanitized the lazy irq state,
|
||||
* and in the latter case it will leave with interrupts hard
|
||||
* disabled and marked as such, so the local_irq_enable() call
|
||||
* in cpu_idle() will properly re-enable everything.
|
||||
* in arch_cpu_idle() will properly re-enable everything.
|
||||
*/
|
||||
bool prep_irq_for_idle(void)
|
||||
{
|
||||
|
@ -113,7 +113,7 @@ arch_initcall(proc_tile_init);
|
||||
* Support /proc/sys/tile directory
|
||||
*/
|
||||
|
||||
static ctl_table unaligned_subtable[] = {
|
||||
static struct ctl_table unaligned_subtable[] = {
|
||||
{
|
||||
.procname = "enabled",
|
||||
.data = &unaligned_fixup,
|
||||
@ -138,7 +138,7 @@ static ctl_table unaligned_subtable[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static ctl_table unaligned_table[] = {
|
||||
static struct ctl_table unaligned_table[] = {
|
||||
{
|
||||
.procname = "unaligned_fixup",
|
||||
.mode = 0555,
|
||||
|
@ -92,12 +92,6 @@ static inline int __gen_sigismember(sigset_t *set, int _sig)
|
||||
? __const_sigismember((set), (sig)) \
|
||||
: __gen_sigismember((set), (sig)))
|
||||
|
||||
static inline int sigfindinword(unsigned long word)
|
||||
{
|
||||
asm("bsfl %1,%0" : "=r"(word) : "rm"(word) : "cc");
|
||||
return word;
|
||||
}
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
#else /* __i386__ */
|
||||
|
@ -3,6 +3,8 @@
|
||||
* - Split from highmem.c
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/swap.h>
|
||||
@ -15,6 +17,7 @@
|
||||
#include <linux/hash.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/printk.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#include <trace/events/block.h>
|
||||
@ -34,7 +37,7 @@ static __init int init_emergency_pool(void)
|
||||
|
||||
page_pool = mempool_create_page_pool(POOL_SIZE, 0);
|
||||
BUG_ON(!page_pool);
|
||||
printk("bounce pool size: %d pages\n", POOL_SIZE);
|
||||
pr_info("pool size: %d pages\n", POOL_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -86,7 +89,7 @@ int init_emergency_isa_pool(void)
|
||||
mempool_free_pages, (void *) 0);
|
||||
BUG_ON(!isa_page_pool);
|
||||
|
||||
printk("isa bounce pool size: %d pages\n", ISA_POOL_SIZE);
|
||||
pr_info("isa pool size: %d pages\n", ISA_POOL_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -243,14 +243,11 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
|
||||
struct nbd_request request;
|
||||
unsigned long size = blk_rq_bytes(req);
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
request.magic = htonl(NBD_REQUEST_MAGIC);
|
||||
request.type = htonl(nbd_cmd(req));
|
||||
|
||||
if (nbd_cmd(req) == NBD_CMD_FLUSH) {
|
||||
/* Other values are reserved for FLUSH requests. */
|
||||
request.from = 0;
|
||||
request.len = 0;
|
||||
} else {
|
||||
if (nbd_cmd(req) != NBD_CMD_FLUSH && nbd_cmd(req) != NBD_CMD_DISC) {
|
||||
request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9);
|
||||
request.len = htonl(size);
|
||||
}
|
||||
|
@ -3470,7 +3470,7 @@ static int cdrom_print_info(const char *header, int val, char *info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cdrom_sysctl_info(ctl_table *ctl, int write,
|
||||
static int cdrom_sysctl_info(struct ctl_table *ctl, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
int pos;
|
||||
@ -3583,7 +3583,7 @@ static void cdrom_update_settings(void)
|
||||
mutex_unlock(&cdrom_mutex);
|
||||
}
|
||||
|
||||
static int cdrom_sysctl_handler(ctl_table *ctl, int write,
|
||||
static int cdrom_sysctl_handler(struct ctl_table *ctl, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
@ -3609,7 +3609,7 @@ static int cdrom_sysctl_handler(ctl_table *ctl, int write,
|
||||
}
|
||||
|
||||
/* Place files in /proc/sys/dev/cdrom */
|
||||
static ctl_table cdrom_table[] = {
|
||||
static struct ctl_table cdrom_table[] = {
|
||||
{
|
||||
.procname = "info",
|
||||
.data = &cdrom_sysctl_settings.info,
|
||||
@ -3655,7 +3655,7 @@ static ctl_table cdrom_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static ctl_table cdrom_cdrom_table[] = {
|
||||
static struct ctl_table cdrom_cdrom_table[] = {
|
||||
{
|
||||
.procname = "cdrom",
|
||||
.maxlen = 0,
|
||||
@ -3666,7 +3666,7 @@ static ctl_table cdrom_cdrom_table[] = {
|
||||
};
|
||||
|
||||
/* Make sure that /proc/sys/dev is there */
|
||||
static ctl_table cdrom_root_table[] = {
|
||||
static struct ctl_table cdrom_root_table[] = {
|
||||
{
|
||||
.procname = "dev",
|
||||
.maxlen = 0,
|
||||
|
@ -1582,10 +1582,10 @@ static int proc_do_uuid(struct ctl_table *table, int write,
|
||||
/*
|
||||
* Return entropy available scaled to integral bits
|
||||
*/
|
||||
static int proc_do_entropy(ctl_table *table, int write,
|
||||
static int proc_do_entropy(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
ctl_table fake_table;
|
||||
struct ctl_table fake_table;
|
||||
int entropy_count;
|
||||
|
||||
entropy_count = *(int *)table->data >> ENTROPY_SHIFT;
|
||||
|
@ -31,7 +31,7 @@
|
||||
#define PARPORT_MIN_SPINTIME_VALUE 1
|
||||
#define PARPORT_MAX_SPINTIME_VALUE 1000
|
||||
|
||||
static int do_active_device(ctl_table *table, int write,
|
||||
static int do_active_device(struct ctl_table *table, int write,
|
||||
void __user *result, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct parport *port = (struct parport *)table->extra1;
|
||||
@ -68,7 +68,7 @@ static int do_active_device(ctl_table *table, int write,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PARPORT_1284
|
||||
static int do_autoprobe(ctl_table *table, int write,
|
||||
static int do_autoprobe(struct ctl_table *table, int write,
|
||||
void __user *result, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct parport_device_info *info = table->extra2;
|
||||
@ -110,9 +110,9 @@ static int do_autoprobe(ctl_table *table, int write,
|
||||
}
|
||||
#endif /* IEEE1284.3 support. */
|
||||
|
||||
static int do_hardware_base_addr (ctl_table *table, int write,
|
||||
void __user *result,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
static int do_hardware_base_addr(struct ctl_table *table, int write,
|
||||
void __user *result,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct parport *port = (struct parport *)table->extra1;
|
||||
char buffer[20];
|
||||
@ -138,9 +138,9 @@ static int do_hardware_base_addr (ctl_table *table, int write,
|
||||
return copy_to_user(result, buffer, len) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int do_hardware_irq (ctl_table *table, int write,
|
||||
void __user *result,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
static int do_hardware_irq(struct ctl_table *table, int write,
|
||||
void __user *result,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct parport *port = (struct parport *)table->extra1;
|
||||
char buffer[20];
|
||||
@ -166,9 +166,9 @@ static int do_hardware_irq (ctl_table *table, int write,
|
||||
return copy_to_user(result, buffer, len) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int do_hardware_dma (ctl_table *table, int write,
|
||||
void __user *result,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
static int do_hardware_dma(struct ctl_table *table, int write,
|
||||
void __user *result,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct parport *port = (struct parport *)table->extra1;
|
||||
char buffer[20];
|
||||
@ -194,9 +194,9 @@ static int do_hardware_dma (ctl_table *table, int write,
|
||||
return copy_to_user(result, buffer, len) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int do_hardware_modes (ctl_table *table, int write,
|
||||
void __user *result,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
static int do_hardware_modes(struct ctl_table *table, int write,
|
||||
void __user *result,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
struct parport *port = (struct parport *)table->extra1;
|
||||
char buffer[40];
|
||||
@ -255,11 +255,11 @@ PARPORT_MAX_SPINTIME_VALUE;
|
||||
|
||||
struct parport_sysctl_table {
|
||||
struct ctl_table_header *sysctl_header;
|
||||
ctl_table vars[12];
|
||||
ctl_table device_dir[2];
|
||||
ctl_table port_dir[2];
|
||||
ctl_table parport_dir[2];
|
||||
ctl_table dev_dir[2];
|
||||
struct ctl_table vars[12];
|
||||
struct ctl_table device_dir[2];
|
||||
struct ctl_table port_dir[2];
|
||||
struct ctl_table parport_dir[2];
|
||||
struct ctl_table dev_dir[2];
|
||||
};
|
||||
|
||||
static const struct parport_sysctl_table parport_sysctl_template = {
|
||||
@ -369,12 +369,12 @@ static const struct parport_sysctl_table parport_sysctl_template = {
|
||||
struct parport_device_sysctl_table
|
||||
{
|
||||
struct ctl_table_header *sysctl_header;
|
||||
ctl_table vars[2];
|
||||
ctl_table device_dir[2];
|
||||
ctl_table devices_root_dir[2];
|
||||
ctl_table port_dir[2];
|
||||
ctl_table parport_dir[2];
|
||||
ctl_table dev_dir[2];
|
||||
struct ctl_table vars[2];
|
||||
struct ctl_table device_dir[2];
|
||||
struct ctl_table devices_root_dir[2];
|
||||
struct ctl_table port_dir[2];
|
||||
struct ctl_table parport_dir[2];
|
||||
struct ctl_table dev_dir[2];
|
||||
};
|
||||
|
||||
static const struct parport_device_sysctl_table
|
||||
@ -422,10 +422,10 @@ parport_device_sysctl_template = {
|
||||
struct parport_default_sysctl_table
|
||||
{
|
||||
struct ctl_table_header *sysctl_header;
|
||||
ctl_table vars[3];
|
||||
ctl_table default_dir[2];
|
||||
ctl_table parport_dir[2];
|
||||
ctl_table dev_dir[2];
|
||||
struct ctl_table vars[3];
|
||||
struct ctl_table default_dir[2];
|
||||
struct ctl_table parport_dir[2];
|
||||
struct ctl_table dev_dir[2];
|
||||
};
|
||||
|
||||
static struct parport_default_sysctl_table
|
||||
|
@ -768,15 +768,10 @@ static int tsi721_enable_msix(struct tsi721_device *priv)
|
||||
}
|
||||
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
|
||||
|
||||
err = pci_enable_msix(priv->pdev, entries, ARRAY_SIZE(entries));
|
||||
err = pci_enable_msix_exact(priv->pdev, entries, ARRAY_SIZE(entries));
|
||||
if (err) {
|
||||
if (err > 0)
|
||||
dev_info(&priv->pdev->dev,
|
||||
"Only %d MSI-X vectors available, "
|
||||
"not using MSI-X\n", err);
|
||||
else
|
||||
dev_err(&priv->pdev->dev,
|
||||
"Failed to enable MSI-X (err=%d)\n", err);
|
||||
dev_err(&priv->pdev->dev,
|
||||
"Failed to enable MSI-X (err=%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -386,12 +386,12 @@ config RTC_DRV_PCF8583
|
||||
will be called rtc-pcf8583.
|
||||
|
||||
config RTC_DRV_M41T80
|
||||
tristate "ST M41T62/65/M41T80/81/82/83/84/85/87"
|
||||
tristate "ST M41T62/65/M41T80/81/82/83/84/85/87 and compatible"
|
||||
help
|
||||
If you say Y here you will get support for the ST M41T60
|
||||
and M41T80 RTC chips series. Currently, the following chips are
|
||||
supported: M41T62, M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
|
||||
M41ST85, and M41ST87.
|
||||
M41ST85, M41ST87, and MicroCrystal RV4162.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-m41t80.
|
||||
@ -573,6 +573,17 @@ config RTC_DRV_DS1305
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-ds1305.
|
||||
|
||||
config RTC_DRV_DS1343
|
||||
select REGMAP_SPI
|
||||
tristate "Dallas/Maxim DS1343/DS1344"
|
||||
help
|
||||
If you say yes here you get support for the
|
||||
Dallas/Maxim DS1343 and DS1344 real time clock chips.
|
||||
Support for trickle charger, alarm is provided.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-ds1343.
|
||||
|
||||
config RTC_DRV_DS1347
|
||||
tristate "Dallas/Maxim DS1347"
|
||||
help
|
||||
@ -650,6 +661,14 @@ config RTC_DRV_RX4581
|
||||
This driver can also be built as a module. If so the module
|
||||
will be called rtc-rx4581.
|
||||
|
||||
config RTC_DRV_MCP795
|
||||
tristate "Microchip MCP795"
|
||||
help
|
||||
If you say yes here you will get support for the Microchip MCP795.
|
||||
|
||||
This driver can also be built as a module. If so the module
|
||||
will be called rtc-mcp795.
|
||||
|
||||
endif # SPI_MASTER
|
||||
|
||||
comment "Platform RTC drivers"
|
||||
@ -758,6 +777,16 @@ config RTC_DRV_DA9055
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-da9055
|
||||
|
||||
config RTC_DRV_DA9063
|
||||
tristate "Dialog Semiconductor DA9063 RTC"
|
||||
depends on MFD_DA9063
|
||||
help
|
||||
If you say yes here you will get support for the RTC subsystem
|
||||
of the Dialog Semiconductor DA9063.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called "rtc-da9063".
|
||||
|
||||
config RTC_DRV_EFI
|
||||
tristate "EFI RTC"
|
||||
depends on IA64
|
||||
@ -1327,6 +1356,15 @@ config RTC_DRV_MOXART
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-moxart
|
||||
|
||||
config RTC_DRV_XGENE
|
||||
tristate "APM X-Gene RTC"
|
||||
help
|
||||
If you say yes here you get support for the APM X-Gene SoC real time
|
||||
clock.
|
||||
|
||||
This driver can also be built as a module, if so, the module
|
||||
will be called "rtc-xgene".
|
||||
|
||||
comment "HID Sensor RTC drivers"
|
||||
|
||||
config RTC_DRV_HID_SENSOR_TIME
|
||||
|
@ -32,6 +32,7 @@ obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
|
||||
obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o
|
||||
obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
|
||||
obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o
|
||||
obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o
|
||||
obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o
|
||||
obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
|
||||
obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o
|
||||
@ -40,6 +41,7 @@ obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o
|
||||
obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o
|
||||
obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o
|
||||
obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
|
||||
obj-$(CONFIG_RTC_DRV_DS1343) += rtc-ds1343.o
|
||||
obj-$(CONFIG_RTC_DRV_DS1347) += rtc-ds1347.o
|
||||
obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
|
||||
obj-$(CONFIG_RTC_DRV_DS1390) += rtc-ds1390.o
|
||||
@ -80,6 +82,7 @@ obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o
|
||||
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
|
||||
obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o
|
||||
obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o
|
||||
obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o
|
||||
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
|
||||
obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o
|
||||
obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
|
||||
@ -135,5 +138,6 @@ obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o
|
||||
obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o
|
||||
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
|
||||
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
|
||||
obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o
|
||||
obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o
|
||||
obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o
|
||||
|
@ -292,7 +292,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year");
|
||||
do {
|
||||
alarm->time.tm_year++;
|
||||
} while (rtc_valid_tm(&alarm->time) != 0);
|
||||
} while (!is_leap_year(alarm->time.tm_year + 1900)
|
||||
&& rtc_valid_tm(&alarm->time) != 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -300,7 +301,16 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
}
|
||||
|
||||
done:
|
||||
return 0;
|
||||
err = rtc_valid_tm(&alarm->time);
|
||||
|
||||
if (err) {
|
||||
dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n",
|
||||
alarm->time.tm_year + 1900, alarm->time.tm_mon + 1,
|
||||
alarm->time.tm_mday, alarm->time.tm_hour, alarm->time.tm_min,
|
||||
alarm->time.tm_sec);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
|
@ -293,7 +293,7 @@ static int pm860x_rtc_dt_init(struct platform_device *pdev,
|
||||
int ret;
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
np = of_find_node_by_name(np, "rtc");
|
||||
np = of_get_child_by_name(np, "rtc");
|
||||
if (!np) {
|
||||
dev_err(&pdev->dev, "failed to find rtc node\n");
|
||||
return -ENODEV;
|
||||
@ -301,6 +301,7 @@ static int pm860x_rtc_dt_init(struct platform_device *pdev,
|
||||
ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc);
|
||||
if (ret)
|
||||
info->vrtc = 0;
|
||||
of_node_put(np);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
@ -48,6 +48,7 @@ struct at91_rtc_config {
|
||||
|
||||
static const struct at91_rtc_config *at91_rtc_config;
|
||||
static DECLARE_COMPLETION(at91_rtc_updated);
|
||||
static DECLARE_COMPLETION(at91_rtc_upd_rdy);
|
||||
static unsigned int at91_alarm_year = AT91_RTC_EPOCH;
|
||||
static void __iomem *at91_rtc_regs;
|
||||
static int irq;
|
||||
@ -161,6 +162,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
|
||||
1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
wait_for_completion(&at91_rtc_upd_rdy);
|
||||
|
||||
/* Stop Time/Calendar from counting */
|
||||
cr = at91_rtc_read(AT91_RTC_CR);
|
||||
at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM);
|
||||
@ -183,7 +186,9 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
|
||||
|
||||
/* Restart Time/Calendar */
|
||||
cr = at91_rtc_read(AT91_RTC_CR);
|
||||
at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_SECEV);
|
||||
at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM));
|
||||
at91_rtc_write_ier(AT91_RTC_SECEV);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -290,8 +295,10 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
|
||||
if (rtsr) { /* this interrupt is shared! Is it ours? */
|
||||
if (rtsr & AT91_RTC_ALARM)
|
||||
events |= (RTC_AF | RTC_IRQF);
|
||||
if (rtsr & AT91_RTC_SECEV)
|
||||
events |= (RTC_UF | RTC_IRQF);
|
||||
if (rtsr & AT91_RTC_SECEV) {
|
||||
complete(&at91_rtc_upd_rdy);
|
||||
at91_rtc_write_idr(AT91_RTC_SECEV);
|
||||
}
|
||||
if (rtsr & AT91_RTC_ACKUPD)
|
||||
complete(&at91_rtc_updated);
|
||||
|
||||
@ -413,6 +420,11 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(rtc);
|
||||
platform_set_drvdata(pdev, rtc);
|
||||
|
||||
/* enable SECEV interrupt in order to initialize at91_rtc_upd_rdy
|
||||
* completion.
|
||||
*/
|
||||
at91_rtc_write_ier(AT91_RTC_SECEV);
|
||||
|
||||
dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ static int bfin_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bfin_rtc *rtc;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
unsigned long timeout = jiffies + HZ;
|
||||
|
||||
dev_dbg_stamp(dev);
|
||||
@ -361,16 +361,17 @@ static int bfin_rtc_probe(struct platform_device *pdev)
|
||||
/* Register our RTC with the RTC framework */
|
||||
rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops,
|
||||
THIS_MODULE);
|
||||
if (unlikely(IS_ERR(rtc->rtc_dev))) {
|
||||
ret = PTR_ERR(rtc->rtc_dev);
|
||||
goto err;
|
||||
}
|
||||
if (unlikely(IS_ERR(rtc->rtc_dev)))
|
||||
return PTR_ERR(rtc->rtc_dev);
|
||||
|
||||
/* Grab the IRQ and init the hardware */
|
||||
ret = devm_request_irq(dev, IRQ_RTC, bfin_rtc_interrupt, 0,
|
||||
pdev->name, dev);
|
||||
if (unlikely(ret))
|
||||
goto err;
|
||||
dev_err(&pdev->dev,
|
||||
"unable to request IRQ; alarm won't work, "
|
||||
"and writes will be delayed\n");
|
||||
|
||||
/* sometimes the bootloader touched things, but the write complete was not
|
||||
* enabled, so let's just do a quick timeout here since the IRQ will not fire ...
|
||||
*/
|
||||
@ -381,9 +382,6 @@ static int bfin_rtc_probe(struct platform_device *pdev)
|
||||
bfin_write_RTC_SWCNT(0);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bfin_rtc_remove(struct platform_device *pdev)
|
||||
|
@ -647,6 +647,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
|
||||
int retval = 0;
|
||||
unsigned char rtc_control;
|
||||
unsigned address_space;
|
||||
u32 flags = 0;
|
||||
|
||||
/* there can be only one ... */
|
||||
if (cmos_rtc.dev)
|
||||
@ -660,9 +661,12 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
|
||||
* REVISIT non-x86 systems may instead use memory space resources
|
||||
* (needing ioremap etc), not i/o space resources like this ...
|
||||
*/
|
||||
ports = request_region(ports->start,
|
||||
resource_size(ports),
|
||||
driver_name);
|
||||
if (RTC_IOMAPPED)
|
||||
ports = request_region(ports->start, resource_size(ports),
|
||||
driver_name);
|
||||
else
|
||||
ports = request_mem_region(ports->start, resource_size(ports),
|
||||
driver_name);
|
||||
if (!ports) {
|
||||
dev_dbg(dev, "i/o registers already in use\n");
|
||||
return -EBUSY;
|
||||
@ -699,6 +703,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
|
||||
* expect CMOS_READ and friends to handle.
|
||||
*/
|
||||
if (info) {
|
||||
if (info->flags)
|
||||
flags = info->flags;
|
||||
if (info->address_space)
|
||||
address_space = info->address_space;
|
||||
|
||||
if (info->rtc_day_alarm && info->rtc_day_alarm < 128)
|
||||
cmos_rtc.day_alrm = info->rtc_day_alarm;
|
||||
if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128)
|
||||
@ -726,18 +735,21 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
|
||||
|
||||
spin_lock_irq(&rtc_lock);
|
||||
|
||||
/* force periodic irq to CMOS reset default of 1024Hz;
|
||||
*
|
||||
* REVISIT it's been reported that at least one x86_64 ALI mobo
|
||||
* doesn't use 32KHz here ... for portability we might need to
|
||||
* do something about other clock frequencies.
|
||||
*/
|
||||
cmos_rtc.rtc->irq_freq = 1024;
|
||||
hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
|
||||
CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT);
|
||||
if (!(flags & CMOS_RTC_FLAGS_NOFREQ)) {
|
||||
/* force periodic irq to CMOS reset default of 1024Hz;
|
||||
*
|
||||
* REVISIT it's been reported that at least one x86_64 ALI
|
||||
* mobo doesn't use 32KHz here ... for portability we might
|
||||
* need to do something about other clock frequencies.
|
||||
*/
|
||||
cmos_rtc.rtc->irq_freq = 1024;
|
||||
hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
|
||||
CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT);
|
||||
}
|
||||
|
||||
/* disable irqs */
|
||||
cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE);
|
||||
if (is_valid_irq(rtc_irq))
|
||||
cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE);
|
||||
|
||||
rtc_control = CMOS_READ(RTC_CONTROL);
|
||||
|
||||
@ -802,14 +814,18 @@ cleanup1:
|
||||
cmos_rtc.dev = NULL;
|
||||
rtc_device_unregister(cmos_rtc.rtc);
|
||||
cleanup0:
|
||||
release_region(ports->start, resource_size(ports));
|
||||
if (RTC_IOMAPPED)
|
||||
release_region(ports->start, resource_size(ports));
|
||||
else
|
||||
release_mem_region(ports->start, resource_size(ports));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void cmos_do_shutdown(void)
|
||||
static void cmos_do_shutdown(int rtc_irq)
|
||||
{
|
||||
spin_lock_irq(&rtc_lock);
|
||||
cmos_irq_disable(&cmos_rtc, RTC_IRQMASK);
|
||||
if (is_valid_irq(rtc_irq))
|
||||
cmos_irq_disable(&cmos_rtc, RTC_IRQMASK);
|
||||
spin_unlock_irq(&rtc_lock);
|
||||
}
|
||||
|
||||
@ -818,7 +834,7 @@ static void __exit cmos_do_remove(struct device *dev)
|
||||
struct cmos_rtc *cmos = dev_get_drvdata(dev);
|
||||
struct resource *ports;
|
||||
|
||||
cmos_do_shutdown();
|
||||
cmos_do_shutdown(cmos->irq);
|
||||
|
||||
sysfs_remove_bin_file(&dev->kobj, &nvram);
|
||||
|
||||
@ -831,7 +847,10 @@ static void __exit cmos_do_remove(struct device *dev)
|
||||
cmos->rtc = NULL;
|
||||
|
||||
ports = cmos->iomem;
|
||||
release_region(ports->start, resource_size(ports));
|
||||
if (RTC_IOMAPPED)
|
||||
release_region(ports->start, resource_size(ports));
|
||||
else
|
||||
release_mem_region(ports->start, resource_size(ports));
|
||||
cmos->iomem = NULL;
|
||||
|
||||
cmos->dev = NULL;
|
||||
@ -1065,10 +1084,13 @@ static void __exit cmos_pnp_remove(struct pnp_dev *pnp)
|
||||
|
||||
static void cmos_pnp_shutdown(struct pnp_dev *pnp)
|
||||
{
|
||||
if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pnp->dev))
|
||||
struct device *dev = &pnp->dev;
|
||||
struct cmos_rtc *cmos = dev_get_drvdata(dev);
|
||||
|
||||
if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(dev))
|
||||
return;
|
||||
|
||||
cmos_do_shutdown();
|
||||
cmos_do_shutdown(cmos->irq);
|
||||
}
|
||||
|
||||
static const struct pnp_device_id rtc_ids[] = {
|
||||
@ -1143,11 +1165,21 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
|
||||
|
||||
static int __init cmos_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *resource;
|
||||
int irq;
|
||||
|
||||
cmos_of_init(pdev);
|
||||
cmos_wake_setup(&pdev->dev);
|
||||
return cmos_do_probe(&pdev->dev,
|
||||
platform_get_resource(pdev, IORESOURCE_IO, 0),
|
||||
platform_get_irq(pdev, 0));
|
||||
|
||||
if (RTC_IOMAPPED)
|
||||
resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
else
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
irq = -1;
|
||||
|
||||
return cmos_do_probe(&pdev->dev, resource, irq);
|
||||
}
|
||||
|
||||
static int __exit cmos_platform_remove(struct platform_device *pdev)
|
||||
@ -1158,10 +1190,13 @@ static int __exit cmos_platform_remove(struct platform_device *pdev)
|
||||
|
||||
static void cmos_platform_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(&pdev->dev))
|
||||
struct device *dev = &pdev->dev;
|
||||
struct cmos_rtc *cmos = dev_get_drvdata(dev);
|
||||
|
||||
if (system_state == SYSTEM_POWER_OFF && !cmos_poweroff(dev))
|
||||
return;
|
||||
|
||||
cmos_do_shutdown();
|
||||
cmos_do_shutdown(cmos->irq);
|
||||
}
|
||||
|
||||
/* work with hotplug and coldplug */
|
||||
|
@ -20,28 +20,28 @@
|
||||
#include <linux/mfd/da9052/da9052.h>
|
||||
#include <linux/mfd/da9052/reg.h>
|
||||
|
||||
#define rtc_err(da9052, fmt, ...) \
|
||||
dev_err(da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
|
||||
#define rtc_err(rtc, fmt, ...) \
|
||||
dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
|
||||
|
||||
struct da9052_rtc {
|
||||
struct rtc_device *rtc;
|
||||
struct da9052 *da9052;
|
||||
};
|
||||
|
||||
static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable)
|
||||
static int da9052_rtc_enable_alarm(struct da9052_rtc *rtc, bool enable)
|
||||
{
|
||||
int ret;
|
||||
if (enable) {
|
||||
ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
|
||||
DA9052_ALARM_Y_ALARM_ON,
|
||||
DA9052_ALARM_Y_ALARM_ON);
|
||||
ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
|
||||
DA9052_ALARM_Y_ALARM_ON|DA9052_ALARM_Y_TICK_ON,
|
||||
DA9052_ALARM_Y_ALARM_ON);
|
||||
if (ret != 0)
|
||||
rtc_err(da9052, "Failed to enable ALM: %d\n", ret);
|
||||
rtc_err(rtc, "Failed to enable ALM: %d\n", ret);
|
||||
} else {
|
||||
ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
|
||||
DA9052_ALARM_Y_ALARM_ON, 0);
|
||||
ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
|
||||
DA9052_ALARM_Y_ALARM_ON|DA9052_ALARM_Y_TICK_ON, 0);
|
||||
if (ret != 0)
|
||||
rtc_err(da9052, "Write error: %d\n", ret);
|
||||
rtc_err(rtc, "Write error: %d\n", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -49,31 +49,20 @@ static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable)
|
||||
static irqreturn_t da9052_rtc_irq(int irq, void *data)
|
||||
{
|
||||
struct da9052_rtc *rtc = data;
|
||||
int ret;
|
||||
|
||||
ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_MI_REG);
|
||||
if (ret < 0) {
|
||||
rtc_err(rtc->da9052, "Read error: %d\n", ret);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (ret & DA9052_ALARMMI_ALARMTYPE) {
|
||||
da9052_rtc_enable_alarm(rtc->da9052, 0);
|
||||
rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
|
||||
} else
|
||||
rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_PF);
|
||||
rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int da9052_read_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
|
||||
static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
|
||||
{
|
||||
int ret;
|
||||
uint8_t v[5];
|
||||
|
||||
ret = da9052_group_read(da9052, DA9052_ALARM_MI_REG, 5, v);
|
||||
ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, v);
|
||||
if (ret != 0) {
|
||||
rtc_err(da9052, "Failed to group read ALM: %d\n", ret);
|
||||
rtc_err(rtc, "Failed to group read ALM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -84,23 +73,33 @@ static int da9052_read_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
|
||||
rtc_tm->tm_min = v[0] & DA9052_RTC_MIN;
|
||||
|
||||
ret = rtc_valid_tm(rtc_tm);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_set_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
|
||||
static int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm)
|
||||
{
|
||||
struct da9052 *da9052 = rtc->da9052;
|
||||
unsigned long alm_time;
|
||||
int ret;
|
||||
uint8_t v[3];
|
||||
|
||||
ret = rtc_tm_to_time(rtc_tm, &alm_time);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (rtc_tm->tm_sec > 0) {
|
||||
alm_time += 60 - rtc_tm->tm_sec;
|
||||
rtc_time_to_tm(alm_time, rtc_tm);
|
||||
}
|
||||
BUG_ON(rtc_tm->tm_sec); /* it will cause repeated irqs if not zero */
|
||||
|
||||
rtc_tm->tm_year -= 100;
|
||||
rtc_tm->tm_mon += 1;
|
||||
|
||||
ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG,
|
||||
DA9052_RTC_MIN, rtc_tm->tm_min);
|
||||
if (ret != 0) {
|
||||
rtc_err(da9052, "Failed to write ALRM MIN: %d\n", ret);
|
||||
rtc_err(rtc, "Failed to write ALRM MIN: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -115,22 +114,22 @@ static int da9052_set_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
|
||||
ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
|
||||
DA9052_RTC_YEAR, rtc_tm->tm_year);
|
||||
if (ret != 0)
|
||||
rtc_err(da9052, "Failed to write ALRM YEAR: %d\n", ret);
|
||||
rtc_err(rtc, "Failed to write ALRM YEAR: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_rtc_get_alarm_status(struct da9052 *da9052)
|
||||
static int da9052_rtc_get_alarm_status(struct da9052_rtc *rtc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = da9052_reg_read(da9052, DA9052_ALARM_Y_REG);
|
||||
ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_Y_REG);
|
||||
if (ret < 0) {
|
||||
rtc_err(da9052, "Failed to read ALM: %d\n", ret);
|
||||
rtc_err(rtc, "Failed to read ALM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret &= DA9052_ALARM_Y_ALARM_ON;
|
||||
return (ret > 0) ? 1 : 0;
|
||||
|
||||
return !!(ret&DA9052_ALARM_Y_ALARM_ON);
|
||||
}
|
||||
|
||||
static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
|
||||
@ -141,7 +140,7 @@ static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
|
||||
|
||||
ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
|
||||
if (ret < 0) {
|
||||
rtc_err(rtc->da9052, "Failed to read RTC time : %d\n", ret);
|
||||
rtc_err(rtc, "Failed to read RTC time : %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -153,18 +152,14 @@ static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
|
||||
rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC;
|
||||
|
||||
ret = rtc_valid_tm(rtc_tm);
|
||||
if (ret != 0) {
|
||||
rtc_err(rtc->da9052, "rtc_valid_tm failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct da9052_rtc *rtc;
|
||||
uint8_t v[6];
|
||||
int ret;
|
||||
|
||||
rtc = dev_get_drvdata(dev);
|
||||
|
||||
@ -175,7 +170,10 @@ static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
v[4] = tm->tm_mon + 1;
|
||||
v[5] = tm->tm_year - 100;
|
||||
|
||||
return da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
|
||||
ret = da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
|
||||
if (ret < 0)
|
||||
rtc_err(rtc, "failed to set RTC time: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
@ -184,13 +182,13 @@ static int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
struct rtc_time *tm = &alrm->time;
|
||||
struct da9052_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
ret = da9052_read_alarm(rtc->da9052, tm);
|
||||
|
||||
if (ret)
|
||||
ret = da9052_read_alarm(rtc, tm);
|
||||
if (ret < 0) {
|
||||
rtc_err(rtc, "failed to read RTC alarm: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
alrm->enabled = da9052_rtc_get_alarm_status(rtc->da9052);
|
||||
|
||||
alrm->enabled = da9052_rtc_get_alarm_status(rtc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -200,16 +198,15 @@ static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
struct rtc_time *tm = &alrm->time;
|
||||
struct da9052_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
ret = da9052_rtc_enable_alarm(rtc->da9052, 0);
|
||||
ret = da9052_rtc_enable_alarm(rtc, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = da9052_set_alarm(rtc->da9052, tm);
|
||||
if (ret)
|
||||
ret = da9052_set_alarm(rtc, tm);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = da9052_rtc_enable_alarm(rtc->da9052, 1);
|
||||
|
||||
ret = da9052_rtc_enable_alarm(rtc, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -217,7 +214,7 @@ static int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct da9052_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
return da9052_rtc_enable_alarm(rtc->da9052, enabled);
|
||||
return da9052_rtc_enable_alarm(rtc, enabled);
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops da9052_rtc_ops = {
|
||||
@ -239,10 +236,23 @@ static int da9052_rtc_probe(struct platform_device *pdev)
|
||||
|
||||
rtc->da9052 = dev_get_drvdata(pdev->dev.parent);
|
||||
platform_set_drvdata(pdev, rtc);
|
||||
|
||||
ret = da9052_reg_write(rtc->da9052, DA9052_BBAT_CONT_REG, 0xFE);
|
||||
if (ret < 0) {
|
||||
rtc_err(rtc,
|
||||
"Failed to setup RTC battery charging: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG,
|
||||
DA9052_ALARM_Y_TICK_ON, 0);
|
||||
if (ret != 0)
|
||||
rtc_err(rtc, "Failed to disable TICKS: %d\n", ret);
|
||||
|
||||
ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM",
|
||||
da9052_rtc_irq, rtc);
|
||||
if (ret != 0) {
|
||||
rtc_err(rtc->da9052, "irq registration failed: %d\n", ret);
|
||||
rtc_err(rtc, "irq registration failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -261,7 +271,7 @@ static struct platform_driver da9052_rtc_driver = {
|
||||
|
||||
module_platform_driver(da9052_rtc_driver);
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
MODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>");
|
||||
MODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:da9052-rtc");
|
||||
|
333
drivers/rtc/rtc-da9063.c
Normal file
333
drivers/rtc/rtc-da9063.c
Normal file
@ -0,0 +1,333 @@
|
||||
/* rtc-da9063.c - Real time clock device driver for DA9063
|
||||
* Copyright (C) 2013-14 Dialog Semiconductor Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/da9063/registers.h>
|
||||
#include <linux/mfd/da9063/core.h>
|
||||
|
||||
#define YEARS_TO_DA9063(year) ((year) - 100)
|
||||
#define MONTHS_TO_DA9063(month) ((month) + 1)
|
||||
#define YEARS_FROM_DA9063(year) ((year) + 100)
|
||||
#define MONTHS_FROM_DA9063(month) ((month) - 1)
|
||||
|
||||
#define RTC_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1)
|
||||
#define RTC_SEC 0
|
||||
#define RTC_MIN 1
|
||||
#define RTC_HOUR 2
|
||||
#define RTC_DAY 3
|
||||
#define RTC_MONTH 4
|
||||
#define RTC_YEAR 5
|
||||
|
||||
struct da9063_rtc {
|
||||
struct rtc_device *rtc_dev;
|
||||
struct da9063 *hw;
|
||||
struct rtc_time alarm_time;
|
||||
bool rtc_sync;
|
||||
};
|
||||
|
||||
static void da9063_data_to_tm(u8 *data, struct rtc_time *tm)
|
||||
{
|
||||
tm->tm_sec = data[RTC_SEC] & DA9063_COUNT_SEC_MASK;
|
||||
tm->tm_min = data[RTC_MIN] & DA9063_COUNT_MIN_MASK;
|
||||
tm->tm_hour = data[RTC_HOUR] & DA9063_COUNT_HOUR_MASK;
|
||||
tm->tm_mday = data[RTC_DAY] & DA9063_COUNT_DAY_MASK;
|
||||
tm->tm_mon = MONTHS_FROM_DA9063(data[RTC_MONTH] &
|
||||
DA9063_COUNT_MONTH_MASK);
|
||||
tm->tm_year = YEARS_FROM_DA9063(data[RTC_YEAR] &
|
||||
DA9063_COUNT_YEAR_MASK);
|
||||
}
|
||||
|
||||
static void da9063_tm_to_data(struct rtc_time *tm, u8 *data)
|
||||
{
|
||||
data[RTC_SEC] &= ~DA9063_COUNT_SEC_MASK;
|
||||
data[RTC_SEC] |= tm->tm_sec & DA9063_COUNT_SEC_MASK;
|
||||
|
||||
data[RTC_MIN] &= ~DA9063_COUNT_MIN_MASK;
|
||||
data[RTC_MIN] |= tm->tm_min & DA9063_COUNT_MIN_MASK;
|
||||
|
||||
data[RTC_HOUR] &= ~DA9063_COUNT_HOUR_MASK;
|
||||
data[RTC_HOUR] |= tm->tm_hour & DA9063_COUNT_HOUR_MASK;
|
||||
|
||||
data[RTC_DAY] &= ~DA9063_COUNT_DAY_MASK;
|
||||
data[RTC_DAY] |= tm->tm_mday & DA9063_COUNT_DAY_MASK;
|
||||
|
||||
data[RTC_MONTH] &= ~DA9063_COUNT_MONTH_MASK;
|
||||
data[RTC_MONTH] |= MONTHS_TO_DA9063(tm->tm_mon) &
|
||||
DA9063_COUNT_MONTH_MASK;
|
||||
|
||||
data[RTC_YEAR] &= ~DA9063_COUNT_YEAR_MASK;
|
||||
data[RTC_YEAR] |= YEARS_TO_DA9063(tm->tm_year) &
|
||||
DA9063_COUNT_YEAR_MASK;
|
||||
}
|
||||
|
||||
static int da9063_rtc_stop_alarm(struct device *dev)
|
||||
{
|
||||
struct da9063_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
return regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y,
|
||||
DA9063_ALARM_ON, 0);
|
||||
}
|
||||
|
||||
static int da9063_rtc_start_alarm(struct device *dev)
|
||||
{
|
||||
struct da9063_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
return regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y,
|
||||
DA9063_ALARM_ON, DA9063_ALARM_ON);
|
||||
}
|
||||
|
||||
static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct da9063_rtc *rtc = dev_get_drvdata(dev);
|
||||
unsigned long tm_secs;
|
||||
unsigned long al_secs;
|
||||
u8 data[RTC_DATA_LEN];
|
||||
int ret;
|
||||
|
||||
ret = regmap_bulk_read(rtc->hw->regmap, DA9063_REG_COUNT_S,
|
||||
data, RTC_DATA_LEN);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to read RTC time data: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(data[RTC_SEC] & DA9063_RTC_READ)) {
|
||||
dev_dbg(dev, "RTC not yet ready to be read by the host\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
da9063_data_to_tm(data, tm);
|
||||
|
||||
rtc_tm_to_time(tm, &tm_secs);
|
||||
rtc_tm_to_time(&rtc->alarm_time, &al_secs);
|
||||
|
||||
/* handle the rtc synchronisation delay */
|
||||
if (rtc->rtc_sync == true && al_secs - tm_secs == 1)
|
||||
memcpy(tm, &rtc->alarm_time, sizeof(struct rtc_time));
|
||||
else
|
||||
rtc->rtc_sync = false;
|
||||
|
||||
return rtc_valid_tm(tm);
|
||||
}
|
||||
|
||||
static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct da9063_rtc *rtc = dev_get_drvdata(dev);
|
||||
u8 data[RTC_DATA_LEN];
|
||||
int ret;
|
||||
|
||||
da9063_tm_to_data(tm, data);
|
||||
ret = regmap_bulk_write(rtc->hw->regmap, DA9063_REG_COUNT_S,
|
||||
data, RTC_DATA_LEN);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to set RTC time data: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
struct da9063_rtc *rtc = dev_get_drvdata(dev);
|
||||
u8 data[RTC_DATA_LEN];
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
ret = regmap_bulk_read(rtc->hw->regmap, DA9063_REG_ALARM_S,
|
||||
&data[RTC_SEC], RTC_DATA_LEN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
da9063_data_to_tm(data, &alrm->time);
|
||||
|
||||
alrm->enabled = !!(data[RTC_YEAR] & DA9063_ALARM_ON);
|
||||
|
||||
ret = regmap_read(rtc->hw->regmap, DA9063_REG_EVENT_A, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (val & (DA9063_E_ALARM))
|
||||
alrm->pending = 1;
|
||||
else
|
||||
alrm->pending = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
struct da9063_rtc *rtc = dev_get_drvdata(dev);
|
||||
u8 data[RTC_DATA_LEN];
|
||||
int ret;
|
||||
|
||||
da9063_tm_to_data(&alrm->time, data);
|
||||
|
||||
ret = da9063_rtc_stop_alarm(dev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to stop alarm: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_bulk_write(rtc->hw->regmap, DA9063_REG_ALARM_S,
|
||||
data, RTC_DATA_LEN);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to write alarm: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rtc->alarm_time = alrm->time;
|
||||
|
||||
if (alrm->enabled) {
|
||||
ret = da9063_rtc_start_alarm(dev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to start alarm: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9063_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
if (enabled)
|
||||
return da9063_rtc_start_alarm(dev);
|
||||
else
|
||||
return da9063_rtc_stop_alarm(dev);
|
||||
}
|
||||
|
||||
static irqreturn_t da9063_alarm_event(int irq, void *data)
|
||||
{
|
||||
struct da9063_rtc *rtc = data;
|
||||
|
||||
regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y,
|
||||
DA9063_ALARM_ON, 0);
|
||||
|
||||
rtc->rtc_sync = true;
|
||||
rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops da9063_rtc_ops = {
|
||||
.read_time = da9063_rtc_read_time,
|
||||
.set_time = da9063_rtc_set_time,
|
||||
.read_alarm = da9063_rtc_read_alarm,
|
||||
.set_alarm = da9063_rtc_set_alarm,
|
||||
.alarm_irq_enable = da9063_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int da9063_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct da9063_rtc *rtc;
|
||||
int irq_alarm;
|
||||
u8 data[RTC_DATA_LEN];
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(da9063->regmap, DA9063_REG_CONTROL_E,
|
||||
DA9063_RTC_EN, DA9063_RTC_EN);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to enable RTC\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(da9063->regmap, DA9063_REG_EN_32K,
|
||||
DA9063_CRYSTAL, DA9063_CRYSTAL);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to run 32kHz oscillator\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_S,
|
||||
DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM,
|
||||
0);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to access RTC alarm register\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_S,
|
||||
DA9063_ALARM_STATUS_ALARM,
|
||||
DA9063_ALARM_STATUS_ALARM);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to access RTC alarm register\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_Y,
|
||||
DA9063_TICK_ON, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to disable TICKs\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = regmap_bulk_read(da9063->regmap, DA9063_REG_ALARM_S,
|
||||
data, RTC_DATA_LEN);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n",
|
||||
ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
|
||||
if (!rtc)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, rtc);
|
||||
|
||||
irq_alarm = platform_get_irq_byname(pdev, "ALARM");
|
||||
ret = devm_request_threaded_irq(&pdev->dev, irq_alarm, NULL,
|
||||
da9063_alarm_event,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
"ALARM", rtc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n",
|
||||
irq_alarm, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rtc->hw = da9063;
|
||||
rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC,
|
||||
&da9063_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(rtc->rtc_dev))
|
||||
return PTR_ERR(rtc->rtc_dev);
|
||||
|
||||
da9063_data_to_tm(data, &rtc->alarm_time);
|
||||
rtc->rtc_sync = false;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver da9063_rtc_driver = {
|
||||
.probe = da9063_rtc_probe,
|
||||
.driver = {
|
||||
.name = DA9063_DRVNAME_RTC,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(da9063_rtc_driver);
|
||||
|
||||
MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>");
|
||||
MODULE_DESCRIPTION("Real time clock device driver for Dialog DA9063");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:" DA9063_DRVNAME_RTC);
|
689
drivers/rtc/rtc-ds1343.c
Normal file
689
drivers/rtc/rtc-ds1343.c
Normal file
@ -0,0 +1,689 @@
|
||||
/* rtc-ds1343.c
|
||||
*
|
||||
* Driver for Dallas Semiconductor DS1343 Low Current, SPI Compatible
|
||||
* Real Time Clock
|
||||
*
|
||||
* Author : Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define DS1343_DRV_VERSION "01.00"
|
||||
#define DALLAS_MAXIM_DS1343 0
|
||||
#define DALLAS_MAXIM_DS1344 1
|
||||
|
||||
/* RTC DS1343 Registers */
|
||||
#define DS1343_SECONDS_REG 0x00
|
||||
#define DS1343_MINUTES_REG 0x01
|
||||
#define DS1343_HOURS_REG 0x02
|
||||
#define DS1343_DAY_REG 0x03
|
||||
#define DS1343_DATE_REG 0x04
|
||||
#define DS1343_MONTH_REG 0x05
|
||||
#define DS1343_YEAR_REG 0x06
|
||||
#define DS1343_ALM0_SEC_REG 0x07
|
||||
#define DS1343_ALM0_MIN_REG 0x08
|
||||
#define DS1343_ALM0_HOUR_REG 0x09
|
||||
#define DS1343_ALM0_DAY_REG 0x0A
|
||||
#define DS1343_ALM1_SEC_REG 0x0B
|
||||
#define DS1343_ALM1_MIN_REG 0x0C
|
||||
#define DS1343_ALM1_HOUR_REG 0x0D
|
||||
#define DS1343_ALM1_DAY_REG 0x0E
|
||||
#define DS1343_CONTROL_REG 0x0F
|
||||
#define DS1343_STATUS_REG 0x10
|
||||
#define DS1343_TRICKLE_REG 0x11
|
||||
|
||||
/* DS1343 Control Registers bits */
|
||||
#define DS1343_EOSC 0x80
|
||||
#define DS1343_DOSF 0x20
|
||||
#define DS1343_EGFIL 0x10
|
||||
#define DS1343_SQW 0x08
|
||||
#define DS1343_INTCN 0x04
|
||||
#define DS1343_A1IE 0x02
|
||||
#define DS1343_A0IE 0x01
|
||||
|
||||
/* DS1343 Status Registers bits */
|
||||
#define DS1343_OSF 0x80
|
||||
#define DS1343_IRQF1 0x02
|
||||
#define DS1343_IRQF0 0x01
|
||||
|
||||
/* DS1343 Trickle Charger Registers bits */
|
||||
#define DS1343_TRICKLE_MAGIC 0xa0
|
||||
#define DS1343_TRICKLE_DS1 0x08
|
||||
#define DS1343_TRICKLE_1K 0x01
|
||||
#define DS1343_TRICKLE_2K 0x02
|
||||
#define DS1343_TRICKLE_4K 0x03
|
||||
|
||||
static const struct spi_device_id ds1343_id[] = {
|
||||
{ "ds1343", DALLAS_MAXIM_DS1343 },
|
||||
{ "ds1344", DALLAS_MAXIM_DS1344 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ds1343_id);
|
||||
|
||||
struct ds1343_priv {
|
||||
struct spi_device *spi;
|
||||
struct rtc_device *rtc;
|
||||
struct regmap *map;
|
||||
struct mutex mutex;
|
||||
unsigned int irqen;
|
||||
int irq;
|
||||
int alarm_sec;
|
||||
int alarm_min;
|
||||
int alarm_hour;
|
||||
int alarm_mday;
|
||||
};
|
||||
|
||||
static int ds1343_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
#ifdef RTC_SET_CHARGE
|
||||
case RTC_SET_CHARGE:
|
||||
{
|
||||
int val;
|
||||
|
||||
if (copy_from_user(&val, (int __user *)arg, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
return regmap_write(priv->map, DS1343_TRICKLE_REG, val);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
static ssize_t ds1343_show_glitchfilter(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int glitch_filt_status, data;
|
||||
|
||||
regmap_read(priv->map, DS1343_CONTROL_REG, &data);
|
||||
|
||||
glitch_filt_status = !!(data & DS1343_EGFIL);
|
||||
|
||||
if (glitch_filt_status)
|
||||
return sprintf(buf, "enabled\n");
|
||||
else
|
||||
return sprintf(buf, "disabled\n");
|
||||
}
|
||||
|
||||
static ssize_t ds1343_store_glitchfilter(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int data;
|
||||
|
||||
regmap_read(priv->map, DS1343_CONTROL_REG, &data);
|
||||
|
||||
if (strncmp(buf, "enabled", 7) == 0)
|
||||
data |= DS1343_EGFIL;
|
||||
|
||||
else if (strncmp(buf, "disabled", 8) == 0)
|
||||
data &= ~(DS1343_EGFIL);
|
||||
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
regmap_write(priv->map, DS1343_CONTROL_REG, data);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(glitch_filter, S_IRUGO | S_IWUSR, ds1343_show_glitchfilter,
|
||||
ds1343_store_glitchfilter);
|
||||
|
||||
static ssize_t ds1343_show_alarmstatus(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int alarmstatus, data;
|
||||
|
||||
regmap_read(priv->map, DS1343_CONTROL_REG, &data);
|
||||
|
||||
alarmstatus = !!(data & DS1343_A0IE);
|
||||
|
||||
if (alarmstatus)
|
||||
return sprintf(buf, "enabled\n");
|
||||
else
|
||||
return sprintf(buf, "disabled\n");
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(alarm_status, S_IRUGO, ds1343_show_alarmstatus, NULL);
|
||||
|
||||
static ssize_t ds1343_show_alarmmode(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int alarm_mode, data;
|
||||
char *alarm_str;
|
||||
|
||||
regmap_read(priv->map, DS1343_ALM0_SEC_REG, &data);
|
||||
alarm_mode = (data & 0x80) >> 4;
|
||||
|
||||
regmap_read(priv->map, DS1343_ALM0_MIN_REG, &data);
|
||||
alarm_mode |= (data & 0x80) >> 5;
|
||||
|
||||
regmap_read(priv->map, DS1343_ALM0_HOUR_REG, &data);
|
||||
alarm_mode |= (data & 0x80) >> 6;
|
||||
|
||||
regmap_read(priv->map, DS1343_ALM0_DAY_REG, &data);
|
||||
alarm_mode |= (data & 0x80) >> 7;
|
||||
|
||||
switch (alarm_mode) {
|
||||
case 15:
|
||||
alarm_str = "each second";
|
||||
break;
|
||||
|
||||
case 7:
|
||||
alarm_str = "seconds match";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
alarm_str = "minutes and seconds match";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
alarm_str = "hours, minutes and seconds match";
|
||||
break;
|
||||
|
||||
case 0:
|
||||
alarm_str = "day, hours, minutes and seconds match";
|
||||
break;
|
||||
|
||||
default:
|
||||
alarm_str = "invalid";
|
||||
break;
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s\n", alarm_str);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(alarm_mode, S_IRUGO, ds1343_show_alarmmode, NULL);
|
||||
|
||||
static ssize_t ds1343_show_tricklecharger(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int data;
|
||||
char *diodes = "disabled", *resistors = " ";
|
||||
|
||||
regmap_read(priv->map, DS1343_TRICKLE_REG, &data);
|
||||
|
||||
if ((data & 0xf0) == DS1343_TRICKLE_MAGIC) {
|
||||
switch (data & 0x0c) {
|
||||
case DS1343_TRICKLE_DS1:
|
||||
diodes = "one diode,";
|
||||
break;
|
||||
|
||||
default:
|
||||
diodes = "no diode,";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (data & 0x03) {
|
||||
case DS1343_TRICKLE_1K:
|
||||
resistors = "1k Ohm";
|
||||
break;
|
||||
|
||||
case DS1343_TRICKLE_2K:
|
||||
resistors = "2k Ohm";
|
||||
break;
|
||||
|
||||
case DS1343_TRICKLE_4K:
|
||||
resistors = "4k Ohm";
|
||||
break;
|
||||
|
||||
default:
|
||||
diodes = "disabled";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s %s\n", diodes, resistors);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(trickle_charger, S_IRUGO, ds1343_show_tricklecharger, NULL);
|
||||
|
||||
static int ds1343_sysfs_register(struct device *dev)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
err = device_create_file(dev, &dev_attr_glitch_filter);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = device_create_file(dev, &dev_attr_trickle_charger);
|
||||
if (err)
|
||||
goto error1;
|
||||
|
||||
if (priv->irq <= 0)
|
||||
return err;
|
||||
|
||||
err = device_create_file(dev, &dev_attr_alarm_mode);
|
||||
if (err)
|
||||
goto error2;
|
||||
|
||||
err = device_create_file(dev, &dev_attr_alarm_status);
|
||||
if (!err)
|
||||
return err;
|
||||
|
||||
device_remove_file(dev, &dev_attr_alarm_mode);
|
||||
|
||||
error2:
|
||||
device_remove_file(dev, &dev_attr_trickle_charger);
|
||||
|
||||
error1:
|
||||
device_remove_file(dev, &dev_attr_glitch_filter);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ds1343_sysfs_unregister(struct device *dev)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
device_remove_file(dev, &dev_attr_glitch_filter);
|
||||
device_remove_file(dev, &dev_attr_trickle_charger);
|
||||
|
||||
if (priv->irq <= 0)
|
||||
return;
|
||||
|
||||
device_remove_file(dev, &dev_attr_alarm_status);
|
||||
device_remove_file(dev, &dev_attr_alarm_mode);
|
||||
}
|
||||
|
||||
static int ds1343_read_time(struct device *dev, struct rtc_time *dt)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
unsigned char buf[7];
|
||||
int res;
|
||||
|
||||
res = regmap_bulk_read(priv->map, DS1343_SECONDS_REG, buf, 7);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
dt->tm_sec = bcd2bin(buf[0]);
|
||||
dt->tm_min = bcd2bin(buf[1]);
|
||||
dt->tm_hour = bcd2bin(buf[2] & 0x3F);
|
||||
dt->tm_wday = bcd2bin(buf[3]) - 1;
|
||||
dt->tm_mday = bcd2bin(buf[4]);
|
||||
dt->tm_mon = bcd2bin(buf[5] & 0x1F) - 1;
|
||||
dt->tm_year = bcd2bin(buf[6]) + 100; /* year offset from 1900 */
|
||||
|
||||
return rtc_valid_tm(dt);
|
||||
}
|
||||
|
||||
static int ds1343_set_time(struct device *dev, struct rtc_time *dt)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int res;
|
||||
|
||||
res = regmap_write(priv->map, DS1343_SECONDS_REG,
|
||||
bin2bcd(dt->tm_sec));
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = regmap_write(priv->map, DS1343_MINUTES_REG,
|
||||
bin2bcd(dt->tm_min));
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = regmap_write(priv->map, DS1343_HOURS_REG,
|
||||
bin2bcd(dt->tm_hour) & 0x3F);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = regmap_write(priv->map, DS1343_DAY_REG,
|
||||
bin2bcd(dt->tm_wday + 1));
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = regmap_write(priv->map, DS1343_DATE_REG,
|
||||
bin2bcd(dt->tm_mday));
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = regmap_write(priv->map, DS1343_MONTH_REG,
|
||||
bin2bcd(dt->tm_mon + 1));
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
dt->tm_year %= 100;
|
||||
|
||||
res = regmap_write(priv->map, DS1343_YEAR_REG,
|
||||
bin2bcd(dt->tm_year));
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ds1343_update_alarm(struct device *dev)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
unsigned int control, stat;
|
||||
unsigned char buf[4];
|
||||
int res = 0;
|
||||
|
||||
res = regmap_read(priv->map, DS1343_CONTROL_REG, &control);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
control &= ~(DS1343_A0IE);
|
||||
stat &= ~(DS1343_IRQF0);
|
||||
|
||||
res = regmap_write(priv->map, DS1343_CONTROL_REG, control);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = regmap_write(priv->map, DS1343_STATUS_REG, stat);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
buf[0] = priv->alarm_sec < 0 || (priv->irqen & RTC_UF) ?
|
||||
0x80 : bin2bcd(priv->alarm_sec) & 0x7F;
|
||||
buf[1] = priv->alarm_min < 0 || (priv->irqen & RTC_UF) ?
|
||||
0x80 : bin2bcd(priv->alarm_min) & 0x7F;
|
||||
buf[2] = priv->alarm_hour < 0 || (priv->irqen & RTC_UF) ?
|
||||
0x80 : bin2bcd(priv->alarm_hour) & 0x3F;
|
||||
buf[3] = priv->alarm_mday < 0 || (priv->irqen & RTC_UF) ?
|
||||
0x80 : bin2bcd(priv->alarm_mday) & 0x7F;
|
||||
|
||||
res = regmap_bulk_write(priv->map, DS1343_ALM0_SEC_REG, buf, 4);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (priv->irqen) {
|
||||
control |= DS1343_A0IE;
|
||||
res = regmap_write(priv->map, DS1343_CONTROL_REG, control);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int res = 0;
|
||||
unsigned int stat;
|
||||
|
||||
if (priv->irq <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
alarm->enabled = !!(priv->irqen & RTC_AF);
|
||||
alarm->pending = !!(stat & DS1343_IRQF0);
|
||||
|
||||
alarm->time.tm_sec = priv->alarm_sec < 0 ? 0 : priv->alarm_sec;
|
||||
alarm->time.tm_min = priv->alarm_min < 0 ? 0 : priv->alarm_min;
|
||||
alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour;
|
||||
alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday;
|
||||
|
||||
alarm->time.tm_mon = -1;
|
||||
alarm->time.tm_year = -1;
|
||||
alarm->time.tm_wday = -1;
|
||||
alarm->time.tm_yday = -1;
|
||||
alarm->time.tm_isdst = -1;
|
||||
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int res = 0;
|
||||
|
||||
if (priv->irq <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
priv->alarm_sec = alarm->time.tm_sec;
|
||||
priv->alarm_min = alarm->time.tm_min;
|
||||
priv->alarm_hour = alarm->time.tm_hour;
|
||||
priv->alarm_mday = alarm->time.tm_mday;
|
||||
|
||||
if (alarm->enabled)
|
||||
priv->irqen |= RTC_AF;
|
||||
|
||||
res = ds1343_update_alarm(dev);
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int ds1343_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_get_drvdata(dev);
|
||||
int res = 0;
|
||||
|
||||
if (priv->irq <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (enabled)
|
||||
priv->irqen |= RTC_AF;
|
||||
else
|
||||
priv->irqen &= ~RTC_AF;
|
||||
|
||||
res = ds1343_update_alarm(dev);
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static irqreturn_t ds1343_thread(int irq, void *dev_id)
|
||||
{
|
||||
struct ds1343_priv *priv = dev_id;
|
||||
unsigned int stat, control;
|
||||
int res = 0;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
if (stat & DS1343_IRQF0) {
|
||||
stat &= ~DS1343_IRQF0;
|
||||
regmap_write(priv->map, DS1343_STATUS_REG, stat);
|
||||
|
||||
res = regmap_read(priv->map, DS1343_CONTROL_REG, &control);
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
control &= ~DS1343_A0IE;
|
||||
regmap_write(priv->map, DS1343_CONTROL_REG, control);
|
||||
|
||||
rtc_update_irq(priv->rtc, 1, RTC_AF | RTC_IRQF);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops ds1343_rtc_ops = {
|
||||
.ioctl = ds1343_ioctl,
|
||||
.read_time = ds1343_read_time,
|
||||
.set_time = ds1343_set_time,
|
||||
.read_alarm = ds1343_read_alarm,
|
||||
.set_alarm = ds1343_set_alarm,
|
||||
.alarm_irq_enable = ds1343_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int ds1343_probe(struct spi_device *spi)
|
||||
{
|
||||
struct ds1343_priv *priv;
|
||||
struct regmap_config config;
|
||||
unsigned int data;
|
||||
int res;
|
||||
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.reg_bits = 8;
|
||||
config.val_bits = 8;
|
||||
config.write_flag_mask = 0x80;
|
||||
|
||||
priv = devm_kzalloc(&spi->dev, sizeof(struct ds1343_priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->spi = spi;
|
||||
mutex_init(&priv->mutex);
|
||||
|
||||
/* RTC DS1347 works in spi mode 3 and
|
||||
* its chip select is active high
|
||||
*/
|
||||
spi->mode = SPI_MODE_3 | SPI_CS_HIGH;
|
||||
spi->bits_per_word = 8;
|
||||
res = spi_setup(spi);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
spi_set_drvdata(spi, priv);
|
||||
|
||||
priv->map = devm_regmap_init_spi(spi, &config);
|
||||
|
||||
if (IS_ERR(priv->map)) {
|
||||
dev_err(&spi->dev, "spi regmap init failed for rtc ds1343\n");
|
||||
return PTR_ERR(priv->map);
|
||||
}
|
||||
|
||||
res = regmap_read(priv->map, DS1343_SECONDS_REG, &data);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
regmap_read(priv->map, DS1343_CONTROL_REG, &data);
|
||||
data |= DS1343_INTCN;
|
||||
data &= ~(DS1343_EOSC | DS1343_A1IE | DS1343_A0IE);
|
||||
regmap_write(priv->map, DS1343_CONTROL_REG, data);
|
||||
|
||||
regmap_read(priv->map, DS1343_STATUS_REG, &data);
|
||||
data &= ~(DS1343_OSF | DS1343_IRQF1 | DS1343_IRQF0);
|
||||
regmap_write(priv->map, DS1343_STATUS_REG, data);
|
||||
|
||||
priv->rtc = devm_rtc_device_register(&spi->dev, "ds1343",
|
||||
&ds1343_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(priv->rtc)) {
|
||||
dev_err(&spi->dev, "unable to register rtc ds1343\n");
|
||||
return PTR_ERR(priv->rtc);
|
||||
}
|
||||
|
||||
priv->irq = spi->irq;
|
||||
|
||||
if (priv->irq >= 0) {
|
||||
res = devm_request_threaded_irq(&spi->dev, spi->irq, NULL,
|
||||
ds1343_thread,
|
||||
IRQF_NO_SUSPEND | IRQF_ONESHOT,
|
||||
"ds1343", priv);
|
||||
if (res) {
|
||||
priv->irq = -1;
|
||||
dev_err(&spi->dev,
|
||||
"unable to request irq for rtc ds1343\n");
|
||||
} else {
|
||||
device_set_wakeup_capable(&spi->dev, 1);
|
||||
}
|
||||
}
|
||||
|
||||
res = ds1343_sysfs_register(&spi->dev);
|
||||
if (res)
|
||||
dev_err(&spi->dev,
|
||||
"unable to create sysfs entries for rtc ds1343\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ds1343_remove(struct spi_device *spi)
|
||||
{
|
||||
struct ds1343_priv *priv = spi_get_drvdata(spi);
|
||||
|
||||
if (spi->irq) {
|
||||
mutex_lock(&priv->mutex);
|
||||
priv->irqen &= ~RTC_AF;
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
devm_free_irq(&spi->dev, spi->irq, priv);
|
||||
}
|
||||
|
||||
spi_set_drvdata(spi, NULL);
|
||||
|
||||
ds1343_sysfs_unregister(&spi->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
static int ds1343_suspend(struct device *dev)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
|
||||
if (spi->irq >= 0 && device_may_wakeup(dev))
|
||||
enable_irq_wake(spi->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ds1343_resume(struct device *dev)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
|
||||
if (spi->irq >= 0 && device_may_wakeup(dev))
|
||||
disable_irq_wake(spi->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ds1343_pm, ds1343_suspend, ds1343_resume);
|
||||
|
||||
static struct spi_driver ds1343_driver = {
|
||||
.driver = {
|
||||
.name = "ds1343",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &ds1343_pm,
|
||||
},
|
||||
.probe = ds1343_probe,
|
||||
.remove = ds1343_remove,
|
||||
.id_table = ds1343_id,
|
||||
};
|
||||
|
||||
module_spi_driver(ds1343_driver);
|
||||
|
||||
MODULE_DESCRIPTION("DS1343 RTC SPI Driver");
|
||||
MODULE_AUTHOR("Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_VERSION(DS1343_DRV_VERSION);
|
@ -219,7 +219,7 @@ static int ds1742_rtc_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id __maybe_unused ds1742_rtc_of_match[] = {
|
||||
static const struct of_device_id __maybe_unused ds1742_rtc_of_match[] = {
|
||||
{ .compatible = "maxim,ds1742", },
|
||||
{ }
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ static inline int
|
||||
compute_yday(efi_time_t *eft)
|
||||
{
|
||||
/* efi_time_t.month is in the [1-12] so, we need -1 */
|
||||
return rtc_year_days(eft->day - 1, eft->month - 1, eft->year);
|
||||
return rtc_year_days(eft->day, eft->month - 1, eft->year);
|
||||
}
|
||||
/*
|
||||
* returns day of the week [0-6] 0=Sunday
|
||||
|
@ -418,6 +418,9 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
|
||||
init.num_parents = 0;
|
||||
hym8563->clkout_hw.init = &init;
|
||||
|
||||
/* optional override of the clockname */
|
||||
of_property_read_string(node, "clock-output-names", &init.name);
|
||||
|
||||
/* register the clock */
|
||||
clk = clk_register(&client->dev, &hym8563->clkout_hw);
|
||||
|
||||
@ -585,7 +588,7 @@ static const struct i2c_device_id hym8563_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, hym8563_id);
|
||||
|
||||
static struct of_device_id hym8563_dt_idtable[] = {
|
||||
static const struct of_device_id hym8563_dt_idtable[] = {
|
||||
{ .compatible = "haoyu,hym8563" },
|
||||
{},
|
||||
};
|
||||
|
@ -278,7 +278,7 @@ static int isl12057_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_device_id isl12057_dt_match[] = {
|
||||
static const struct of_device_id isl12057_dt_match[] = {
|
||||
{ .compatible = "isl,isl12057" },
|
||||
{ },
|
||||
};
|
||||
|
@ -66,8 +66,6 @@
|
||||
#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
|
||||
#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */
|
||||
|
||||
#define DRV_VERSION "0.05"
|
||||
|
||||
static DEFINE_MUTEX(m41t80_rtc_mutex);
|
||||
static const struct i2c_device_id m41t80_id[] = {
|
||||
{ "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
|
||||
@ -80,6 +78,7 @@ static const struct i2c_device_id m41t80_id[] = {
|
||||
{ "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
|
||||
{ "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
|
||||
{ "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
|
||||
{ "rv4162", M41T80_FEATURE_SQ | M41T80_FEATURE_WD | M41T80_FEATURE_SQ_ALT },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, m41t80_id);
|
||||
@ -232,7 +231,7 @@ static ssize_t m41t80_sysfs_show_flags(struct device *dev,
|
||||
|
||||
val = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
|
||||
if (val < 0)
|
||||
return -EIO;
|
||||
return val;
|
||||
return sprintf(buf, "%#x\n", val);
|
||||
}
|
||||
static DEVICE_ATTR(flags, S_IRUGO, m41t80_sysfs_show_flags, NULL);
|
||||
@ -252,7 +251,7 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
|
||||
reg_sqw = M41T80_REG_WDAY;
|
||||
val = i2c_smbus_read_byte_data(client, reg_sqw);
|
||||
if (val < 0)
|
||||
return -EIO;
|
||||
return val;
|
||||
val = (val >> 4) & 0xf;
|
||||
switch (val) {
|
||||
case 0:
|
||||
@ -271,7 +270,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct m41t80_data *clientdata = i2c_get_clientdata(client);
|
||||
int almon, sqw, reg_sqw;
|
||||
int almon, sqw, reg_sqw, rc;
|
||||
int val = simple_strtoul(buf, NULL, 0);
|
||||
|
||||
if (!(clientdata->features & M41T80_FEATURE_SQ))
|
||||
@ -291,21 +290,30 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
|
||||
/* disable SQW, set SQW frequency & re-enable */
|
||||
almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
|
||||
if (almon < 0)
|
||||
return -EIO;
|
||||
return almon;
|
||||
reg_sqw = M41T80_REG_SQW;
|
||||
if (clientdata->features & M41T80_FEATURE_SQ_ALT)
|
||||
reg_sqw = M41T80_REG_WDAY;
|
||||
sqw = i2c_smbus_read_byte_data(client, reg_sqw);
|
||||
if (sqw < 0)
|
||||
return -EIO;
|
||||
return sqw;
|
||||
sqw = (sqw & 0x0f) | (val << 4);
|
||||
if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
|
||||
almon & ~M41T80_ALMON_SQWE) < 0 ||
|
||||
i2c_smbus_write_byte_data(client, reg_sqw, sqw) < 0)
|
||||
return -EIO;
|
||||
if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
|
||||
almon | M41T80_ALMON_SQWE) < 0)
|
||||
return -EIO;
|
||||
|
||||
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
|
||||
almon & ~M41T80_ALMON_SQWE);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (val) {
|
||||
rc = i2c_smbus_write_byte_data(client, reg_sqw, sqw);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
|
||||
almon | M41T80_ALMON_SQWE);
|
||||
if (rc <0)
|
||||
return rc;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
|
||||
@ -629,40 +637,28 @@ static int m41t80_probe(struct i2c_client *client,
|
||||
struct m41t80_data *clientdata = NULL;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
|
||||
| I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
rc = -ENODEV;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dev_info(&client->dev,
|
||||
"chip found, driver version " DRV_VERSION "\n");
|
||||
| I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -ENODEV;
|
||||
|
||||
clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata),
|
||||
GFP_KERNEL);
|
||||
if (!clientdata) {
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
if (!clientdata)
|
||||
return -ENOMEM;
|
||||
|
||||
clientdata->features = id->driver_data;
|
||||
i2c_set_clientdata(client, clientdata);
|
||||
|
||||
rtc = devm_rtc_device_register(&client->dev, client->name,
|
||||
&m41t80_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(rtc)) {
|
||||
rc = PTR_ERR(rtc);
|
||||
rtc = NULL;
|
||||
goto exit;
|
||||
}
|
||||
if (IS_ERR(rtc))
|
||||
return PTR_ERR(rtc);
|
||||
|
||||
clientdata->rtc = rtc;
|
||||
|
||||
/* Make sure HT (Halt Update) bit is cleared */
|
||||
rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
|
||||
if (rc < 0)
|
||||
goto ht_err;
|
||||
|
||||
if (rc & M41T80_ALHOUR_HT) {
|
||||
if (rc >= 0 && rc & M41T80_ALHOUR_HT) {
|
||||
if (clientdata->features & M41T80_FEATURE_HT) {
|
||||
m41t80_get_datetime(client, &tm);
|
||||
dev_info(&client->dev, "HT bit was set!\n");
|
||||
@ -673,53 +669,44 @@ static int m41t80_probe(struct i2c_client *client,
|
||||
tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
|
||||
tm.tm_min, tm.tm_sec);
|
||||
}
|
||||
if (i2c_smbus_write_byte_data(client,
|
||||
M41T80_REG_ALARM_HOUR,
|
||||
rc & ~M41T80_ALHOUR_HT) < 0)
|
||||
goto ht_err;
|
||||
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR,
|
||||
rc & ~M41T80_ALHOUR_HT);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
dev_err(&client->dev, "Can't clear HT bit\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Make sure ST (stop) bit is cleared */
|
||||
rc = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
|
||||
if (rc < 0)
|
||||
goto st_err;
|
||||
|
||||
if (rc & M41T80_SEC_ST) {
|
||||
if (i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
|
||||
rc & ~M41T80_SEC_ST) < 0)
|
||||
goto st_err;
|
||||
if (rc >= 0 && rc & M41T80_SEC_ST)
|
||||
rc = i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
|
||||
rc & ~M41T80_SEC_ST);
|
||||
if (rc < 0) {
|
||||
dev_err(&client->dev, "Can't clear ST bit\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = m41t80_sysfs_register(&client->dev);
|
||||
if (rc)
|
||||
goto exit;
|
||||
return rc;
|
||||
|
||||
#ifdef CONFIG_RTC_DRV_M41T80_WDT
|
||||
if (clientdata->features & M41T80_FEATURE_HT) {
|
||||
save_client = client;
|
||||
rc = misc_register(&wdt_dev);
|
||||
if (rc)
|
||||
goto exit;
|
||||
return rc;
|
||||
rc = register_reboot_notifier(&wdt_notifier);
|
||||
if (rc) {
|
||||
misc_deregister(&wdt_dev);
|
||||
goto exit;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
st_err:
|
||||
rc = -EIO;
|
||||
dev_err(&client->dev, "Can't clear ST bit\n");
|
||||
goto exit;
|
||||
ht_err:
|
||||
rc = -EIO;
|
||||
dev_err(&client->dev, "Can't clear HT bit\n");
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int m41t80_remove(struct i2c_client *client)
|
||||
@ -750,4 +737,3 @@ module_i2c_driver(m41t80_driver);
|
||||
MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
|
||||
MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
199
drivers/rtc/rtc-mcp795.c
Normal file
199
drivers/rtc/rtc-mcp795.c
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* SPI Driver for Microchip MCP795 RTC
|
||||
*
|
||||
* Copyright (C) Josef Gajdusek <atx@atx.name>
|
||||
*
|
||||
* based on other Linux RTC drivers
|
||||
*
|
||||
* Device datasheet:
|
||||
* http://ww1.microchip.com/downloads/en/DeviceDoc/22280A.pdf
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* */
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
/* MCP795 Instructions, see datasheet table 3-1 */
|
||||
#define MCP795_EEREAD 0x03
|
||||
#define MCP795_EEWRITE 0x02
|
||||
#define MCP795_EEWRDI 0x04
|
||||
#define MCP795_EEWREN 0x06
|
||||
#define MCP795_SRREAD 0x05
|
||||
#define MCP795_SRWRITE 0x01
|
||||
#define MCP795_READ 0x13
|
||||
#define MCP795_WRITE 0x12
|
||||
#define MCP795_UNLOCK 0x14
|
||||
#define MCP795_IDWRITE 0x32
|
||||
#define MCP795_IDREAD 0x33
|
||||
#define MCP795_CLRWDT 0x44
|
||||
#define MCP795_CLRRAM 0x54
|
||||
|
||||
#define MCP795_ST_BIT 0x80
|
||||
#define MCP795_24_BIT 0x40
|
||||
|
||||
static int mcp795_rtcc_read(struct device *dev, u8 addr, u8 *buf, u8 count)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
int ret;
|
||||
u8 tx[2];
|
||||
|
||||
tx[0] = MCP795_READ;
|
||||
tx[1] = addr;
|
||||
ret = spi_write_then_read(spi, tx, sizeof(tx), buf, count);
|
||||
|
||||
if (ret)
|
||||
dev_err(dev, "Failed reading %d bytes from address %x.\n",
|
||||
count, addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcp795_rtcc_write(struct device *dev, u8 addr, u8 *data, u8 count)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
int ret;
|
||||
u8 tx[2 + count];
|
||||
|
||||
tx[0] = MCP795_WRITE;
|
||||
tx[1] = addr;
|
||||
memcpy(&tx[2], data, count);
|
||||
|
||||
ret = spi_write(spi, tx, 2 + count);
|
||||
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to write %d bytes to address %x.\n",
|
||||
count, addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcp795_rtcc_set_bits(struct device *dev, u8 addr, u8 mask, u8 state)
|
||||
{
|
||||
int ret;
|
||||
u8 tmp;
|
||||
|
||||
ret = mcp795_rtcc_read(dev, addr, &tmp, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((tmp & mask) != state) {
|
||||
tmp = (tmp & ~mask) | state;
|
||||
ret = mcp795_rtcc_write(dev, addr, &tmp, 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcp795_set_time(struct device *dev, struct rtc_time *tim)
|
||||
{
|
||||
int ret;
|
||||
u8 data[7];
|
||||
|
||||
/* Read first, so we can leave config bits untouched */
|
||||
ret = mcp795_rtcc_read(dev, 0x01, data, sizeof(data));
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data[0] = (data[0] & 0x80) | ((tim->tm_sec / 10) << 4) | (tim->tm_sec % 10);
|
||||
data[1] = (data[1] & 0x80) | ((tim->tm_min / 10) << 4) | (tim->tm_min % 10);
|
||||
data[2] = ((tim->tm_hour / 10) << 4) | (tim->tm_hour % 10);
|
||||
data[4] = ((tim->tm_mday / 10) << 4) | ((tim->tm_mday) % 10);
|
||||
data[5] = (data[5] & 0x10) | (tim->tm_mon / 10) | (tim->tm_mon % 10);
|
||||
|
||||
if (tim->tm_year > 100)
|
||||
tim->tm_year -= 100;
|
||||
|
||||
data[6] = ((tim->tm_year / 10) << 4) | (tim->tm_year % 10);
|
||||
|
||||
ret = mcp795_rtcc_write(dev, 0x01, data, sizeof(data));
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_dbg(dev, "Set mcp795: %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||
tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
|
||||
tim->tm_hour, tim->tm_min, tim->tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mcp795_read_time(struct device *dev, struct rtc_time *tim)
|
||||
{
|
||||
int ret;
|
||||
u8 data[7];
|
||||
|
||||
ret = mcp795_rtcc_read(dev, 0x01, data, sizeof(data));
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tim->tm_sec = ((data[0] & 0x70) >> 4) * 10 + (data[0] & 0x0f);
|
||||
tim->tm_min = ((data[1] & 0x70) >> 4) * 10 + (data[1] & 0x0f);
|
||||
tim->tm_hour = ((data[2] & 0x30) >> 4) * 10 + (data[2] & 0x0f);
|
||||
tim->tm_mday = ((data[4] & 0x30) >> 4) * 10 + (data[4] & 0x0f);
|
||||
tim->tm_mon = ((data[5] & 0x10) >> 4) * 10 + (data[5] & 0x0f);
|
||||
tim->tm_year = ((data[6] & 0xf0) >> 4) * 10 + (data[6] & 0x0f) + 100; /* Assume we are in 20xx */
|
||||
|
||||
dev_dbg(dev, "Read from mcp795: %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||
tim->tm_year + 1900, tim->tm_mon, tim->tm_mday,
|
||||
tim->tm_hour, tim->tm_min, tim->tm_sec);
|
||||
|
||||
return rtc_valid_tm(tim);
|
||||
}
|
||||
|
||||
static struct rtc_class_ops mcp795_rtc_ops = {
|
||||
.read_time = mcp795_read_time,
|
||||
.set_time = mcp795_set_time
|
||||
};
|
||||
|
||||
static int mcp795_probe(struct spi_device *spi)
|
||||
{
|
||||
struct rtc_device *rtc;
|
||||
int ret;
|
||||
|
||||
spi->mode = SPI_MODE_0;
|
||||
spi->bits_per_word = 8;
|
||||
ret = spi_setup(spi);
|
||||
if (ret) {
|
||||
dev_err(&spi->dev, "Unable to setup SPI\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start the oscillator */
|
||||
mcp795_rtcc_set_bits(&spi->dev, 0x01, MCP795_ST_BIT, MCP795_ST_BIT);
|
||||
/* Clear the 12 hour mode flag*/
|
||||
mcp795_rtcc_set_bits(&spi->dev, 0x03, MCP795_24_BIT, 0);
|
||||
|
||||
rtc = devm_rtc_device_register(&spi->dev, "rtc-mcp795",
|
||||
&mcp795_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(rtc))
|
||||
return PTR_ERR(rtc);
|
||||
|
||||
spi_set_drvdata(spi, rtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver mcp795_driver = {
|
||||
.driver = {
|
||||
.name = "rtc-mcp795",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = mcp795_probe,
|
||||
};
|
||||
|
||||
module_spi_driver(mcp795_driver);
|
||||
|
||||
MODULE_DESCRIPTION("MCP795 RTC SPI Driver");
|
||||
MODULE_AUTHOR("Josef Gajdusek <atx@atx.name>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("spi:mcp795");
|
@ -319,7 +319,7 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_device_id rtc_mv_of_match_table[] = {
|
||||
static const struct of_device_id rtc_mv_of_match_table[] = {
|
||||
{ .compatible = "marvell,orion-rtc", },
|
||||
{}
|
||||
};
|
||||
|
@ -73,43 +73,52 @@
|
||||
#define OMAP_RTC_IRQWAKEEN 0x7c
|
||||
|
||||
/* OMAP_RTC_CTRL_REG bit fields: */
|
||||
#define OMAP_RTC_CTRL_SPLIT (1<<7)
|
||||
#define OMAP_RTC_CTRL_DISABLE (1<<6)
|
||||
#define OMAP_RTC_CTRL_SET_32_COUNTER (1<<5)
|
||||
#define OMAP_RTC_CTRL_TEST (1<<4)
|
||||
#define OMAP_RTC_CTRL_MODE_12_24 (1<<3)
|
||||
#define OMAP_RTC_CTRL_AUTO_COMP (1<<2)
|
||||
#define OMAP_RTC_CTRL_ROUND_30S (1<<1)
|
||||
#define OMAP_RTC_CTRL_STOP (1<<0)
|
||||
#define OMAP_RTC_CTRL_SPLIT BIT(7)
|
||||
#define OMAP_RTC_CTRL_DISABLE BIT(6)
|
||||
#define OMAP_RTC_CTRL_SET_32_COUNTER BIT(5)
|
||||
#define OMAP_RTC_CTRL_TEST BIT(4)
|
||||
#define OMAP_RTC_CTRL_MODE_12_24 BIT(3)
|
||||
#define OMAP_RTC_CTRL_AUTO_COMP BIT(2)
|
||||
#define OMAP_RTC_CTRL_ROUND_30S BIT(1)
|
||||
#define OMAP_RTC_CTRL_STOP BIT(0)
|
||||
|
||||
/* OMAP_RTC_STATUS_REG bit fields: */
|
||||
#define OMAP_RTC_STATUS_POWER_UP (1<<7)
|
||||
#define OMAP_RTC_STATUS_ALARM (1<<6)
|
||||
#define OMAP_RTC_STATUS_1D_EVENT (1<<5)
|
||||
#define OMAP_RTC_STATUS_1H_EVENT (1<<4)
|
||||
#define OMAP_RTC_STATUS_1M_EVENT (1<<3)
|
||||
#define OMAP_RTC_STATUS_1S_EVENT (1<<2)
|
||||
#define OMAP_RTC_STATUS_RUN (1<<1)
|
||||
#define OMAP_RTC_STATUS_BUSY (1<<0)
|
||||
#define OMAP_RTC_STATUS_POWER_UP BIT(7)
|
||||
#define OMAP_RTC_STATUS_ALARM BIT(6)
|
||||
#define OMAP_RTC_STATUS_1D_EVENT BIT(5)
|
||||
#define OMAP_RTC_STATUS_1H_EVENT BIT(4)
|
||||
#define OMAP_RTC_STATUS_1M_EVENT BIT(3)
|
||||
#define OMAP_RTC_STATUS_1S_EVENT BIT(2)
|
||||
#define OMAP_RTC_STATUS_RUN BIT(1)
|
||||
#define OMAP_RTC_STATUS_BUSY BIT(0)
|
||||
|
||||
/* OMAP_RTC_INTERRUPTS_REG bit fields: */
|
||||
#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
|
||||
#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
|
||||
#define OMAP_RTC_INTERRUPTS_IT_ALARM BIT(3)
|
||||
#define OMAP_RTC_INTERRUPTS_IT_TIMER BIT(2)
|
||||
|
||||
/* OMAP_RTC_OSC_REG bit fields: */
|
||||
#define OMAP_RTC_OSC_32KCLK_EN BIT(6)
|
||||
|
||||
/* OMAP_RTC_IRQWAKEEN bit fields: */
|
||||
#define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN (1<<1)
|
||||
#define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1)
|
||||
|
||||
/* OMAP_RTC_KICKER values */
|
||||
#define KICK0_VALUE 0x83e70b13
|
||||
#define KICK1_VALUE 0x95a4f1e0
|
||||
|
||||
#define OMAP_RTC_HAS_KICKER 0x1
|
||||
#define OMAP_RTC_HAS_KICKER BIT(0)
|
||||
|
||||
/*
|
||||
* Few RTC IP revisions has special WAKE-EN Register to enable Wakeup
|
||||
* generation for event Alarm.
|
||||
*/
|
||||
#define OMAP_RTC_HAS_IRQWAKEEN 0x2
|
||||
#define OMAP_RTC_HAS_IRQWAKEEN BIT(1)
|
||||
|
||||
/*
|
||||
* Some RTC IP revisions (like those in AM335x and DRA7x) need
|
||||
* the 32KHz clock to be explicitly enabled.
|
||||
*/
|
||||
#define OMAP_RTC_HAS_32KCLK_EN BIT(2)
|
||||
|
||||
static void __iomem *rtc_base;
|
||||
|
||||
@ -162,17 +171,28 @@ static irqreturn_t rtc_irq(int irq, void *rtc)
|
||||
|
||||
static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
u8 reg;
|
||||
u8 reg, irqwake_reg = 0;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
const struct platform_device_id *id_entry =
|
||||
platform_get_device_id(pdev);
|
||||
|
||||
local_irq_disable();
|
||||
rtc_wait_not_busy();
|
||||
reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
|
||||
if (enabled)
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
|
||||
irqwake_reg = rtc_read(OMAP_RTC_IRQWAKEEN);
|
||||
|
||||
if (enabled) {
|
||||
reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
|
||||
else
|
||||
irqwake_reg |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
|
||||
} else {
|
||||
reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
|
||||
irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
|
||||
}
|
||||
rtc_wait_not_busy();
|
||||
rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
|
||||
rtc_write(irqwake_reg, OMAP_RTC_IRQWAKEEN);
|
||||
local_irq_enable();
|
||||
|
||||
return 0;
|
||||
@ -272,7 +292,10 @@ static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
||||
|
||||
static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
||||
{
|
||||
u8 reg;
|
||||
u8 reg, irqwake_reg = 0;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
const struct platform_device_id *id_entry =
|
||||
platform_get_device_id(pdev);
|
||||
|
||||
if (tm2bcd(&alm->time) < 0)
|
||||
return -EINVAL;
|
||||
@ -288,11 +311,19 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
||||
rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG);
|
||||
|
||||
reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
|
||||
if (alm->enabled)
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
|
||||
irqwake_reg = rtc_read(OMAP_RTC_IRQWAKEEN);
|
||||
|
||||
if (alm->enabled) {
|
||||
reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
|
||||
else
|
||||
irqwake_reg |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
|
||||
} else {
|
||||
reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
|
||||
irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
|
||||
}
|
||||
rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN)
|
||||
rtc_write(irqwake_reg, OMAP_RTC_IRQWAKEEN);
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
@ -319,7 +350,8 @@ static struct platform_device_id omap_rtc_devtype[] = {
|
||||
},
|
||||
[OMAP_RTC_DATA_AM3352_IDX] = {
|
||||
.name = "am3352-rtc",
|
||||
.driver_data = OMAP_RTC_HAS_KICKER | OMAP_RTC_HAS_IRQWAKEEN,
|
||||
.driver_data = OMAP_RTC_HAS_KICKER | OMAP_RTC_HAS_IRQWAKEEN |
|
||||
OMAP_RTC_HAS_32KCLK_EN,
|
||||
},
|
||||
[OMAP_RTC_DATA_DA830_IDX] = {
|
||||
.name = "da830-rtc",
|
||||
@ -352,6 +384,12 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
|
||||
if (of_id)
|
||||
pdev->id_entry = of_id->data;
|
||||
|
||||
id_entry = platform_get_device_id(pdev);
|
||||
if (!id_entry) {
|
||||
dev_err(&pdev->dev, "no matching device entry\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
omap_rtc_timer = platform_get_irq(pdev, 0);
|
||||
if (omap_rtc_timer <= 0) {
|
||||
pr_debug("%s: no update irq?\n", pdev->name);
|
||||
@ -373,8 +411,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
id_entry = platform_get_device_id(pdev);
|
||||
if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) {
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_KICKER) {
|
||||
rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG);
|
||||
rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG);
|
||||
}
|
||||
@ -393,6 +430,10 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
|
||||
*/
|
||||
rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
|
||||
|
||||
/* enable RTC functional clock */
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_32KCLK_EN)
|
||||
rtc_writel(OMAP_RTC_OSC_32KCLK_EN, OMAP_RTC_OSC_REG);
|
||||
|
||||
/* clear old status */
|
||||
reg = rtc_read(OMAP_RTC_STATUS_REG);
|
||||
if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) {
|
||||
@ -452,7 +493,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
fail0:
|
||||
if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_KICKER)
|
||||
rtc_writel(0, OMAP_RTC_KICK0_REG);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
@ -469,7 +510,7 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
|
||||
/* leave rtc running, but disable irqs */
|
||||
rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
|
||||
|
||||
if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_KICKER)
|
||||
rtc_writel(0, OMAP_RTC_KICK0_REG);
|
||||
|
||||
/* Disable the clock/module */
|
||||
@ -484,28 +525,16 @@ static u8 irqstat;
|
||||
|
||||
static int omap_rtc_suspend(struct device *dev)
|
||||
{
|
||||
u8 irqwake_stat;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
const struct platform_device_id *id_entry =
|
||||
platform_get_device_id(pdev);
|
||||
|
||||
irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
|
||||
|
||||
/* FIXME the RTC alarm is not currently acting as a wakeup event
|
||||
* source on some platforms, and in fact this enable() call is just
|
||||
* saving a flag that's never used...
|
||||
*/
|
||||
if (device_may_wakeup(dev)) {
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(omap_rtc_alarm);
|
||||
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) {
|
||||
irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN);
|
||||
irqwake_stat |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
|
||||
rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN);
|
||||
}
|
||||
} else {
|
||||
else
|
||||
rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
|
||||
}
|
||||
|
||||
/* Disable the clock/module */
|
||||
pm_runtime_put_sync(dev);
|
||||
@ -515,25 +544,14 @@ static int omap_rtc_suspend(struct device *dev)
|
||||
|
||||
static int omap_rtc_resume(struct device *dev)
|
||||
{
|
||||
u8 irqwake_stat;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
const struct platform_device_id *id_entry =
|
||||
platform_get_device_id(pdev);
|
||||
|
||||
/* Enable the clock/module so that we can access the registers */
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
if (device_may_wakeup(dev)) {
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(omap_rtc_alarm);
|
||||
|
||||
if (id_entry->driver_data & OMAP_RTC_HAS_IRQWAKEEN) {
|
||||
irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN);
|
||||
irqwake_stat &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
|
||||
rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN);
|
||||
}
|
||||
} else {
|
||||
else
|
||||
rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -352,7 +352,7 @@ static SIMPLE_DEV_PM_OPS(palmas_rtc_pm_ops, palmas_rtc_suspend,
|
||||
palmas_rtc_resume);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_device_id of_palmas_rtc_match[] = {
|
||||
static const struct of_device_id of_palmas_rtc_match[] = {
|
||||
{ .compatible = "ti,palmas-rtc"},
|
||||
{ },
|
||||
};
|
||||
|
@ -389,7 +389,7 @@ static int __exit pxa_rtc_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_device_id pxa_rtc_dt_ids[] = {
|
||||
static const struct of_device_id pxa_rtc_dt_ids[] = {
|
||||
{ .compatible = "marvell,pxa-rtc" },
|
||||
{}
|
||||
};
|
||||
|
@ -338,7 +338,7 @@ static SIMPLE_DEV_PM_OPS(sa1100_rtc_pm_ops, sa1100_rtc_suspend,
|
||||
sa1100_rtc_resume);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct of_device_id sa1100_rtc_dt_ids[] = {
|
||||
static const struct of_device_id sa1100_rtc_dt_ids[] = {
|
||||
{ .compatible = "mrvl,sa1100-rtc", },
|
||||
{ .compatible = "mrvl,mmp-rtc", },
|
||||
{}
|
||||
|
278
drivers/rtc/rtc-xgene.c
Normal file
278
drivers/rtc/rtc-xgene.c
Normal file
@ -0,0 +1,278 @@
|
||||
/*
|
||||
* APM X-Gene SoC Real Time Clock Driver
|
||||
*
|
||||
* Copyright (c) 2014, Applied Micro Circuits Corporation
|
||||
* Author: Rameshwar Prasad Sahu <rsahu@apm.com>
|
||||
* Loc Ho <lho@apm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
/* RTC CSR Registers */
|
||||
#define RTC_CCVR 0x00
|
||||
#define RTC_CMR 0x04
|
||||
#define RTC_CLR 0x08
|
||||
#define RTC_CCR 0x0C
|
||||
#define RTC_CCR_IE BIT(0)
|
||||
#define RTC_CCR_MASK BIT(1)
|
||||
#define RTC_CCR_EN BIT(2)
|
||||
#define RTC_CCR_WEN BIT(3)
|
||||
#define RTC_STAT 0x10
|
||||
#define RTC_STAT_BIT BIT(0)
|
||||
#define RTC_RSTAT 0x14
|
||||
#define RTC_EOI 0x18
|
||||
#define RTC_VER 0x1C
|
||||
|
||||
struct xgene_rtc_dev {
|
||||
struct rtc_device *rtc;
|
||||
struct device *dev;
|
||||
unsigned long alarm_time;
|
||||
void __iomem *csr_base;
|
||||
struct clk *clk;
|
||||
unsigned int irq_wake;
|
||||
};
|
||||
|
||||
static int xgene_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
|
||||
|
||||
rtc_time_to_tm(readl(pdata->csr_base + RTC_CCVR), tm);
|
||||
return rtc_valid_tm(tm);
|
||||
}
|
||||
|
||||
static int xgene_rtc_set_mmss(struct device *dev, unsigned long secs)
|
||||
{
|
||||
struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
|
||||
|
||||
/*
|
||||
* NOTE: After the following write, the RTC_CCVR is only reflected
|
||||
* after the update cycle of 1 seconds.
|
||||
*/
|
||||
writel((u32) secs, pdata->csr_base + RTC_CLR);
|
||||
readl(pdata->csr_base + RTC_CLR); /* Force a barrier */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xgene_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
|
||||
|
||||
rtc_time_to_tm(pdata->alarm_time, &alrm->time);
|
||||
alrm->enabled = readl(pdata->csr_base + RTC_CCR) & RTC_CCR_IE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xgene_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
|
||||
{
|
||||
struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
|
||||
u32 ccr;
|
||||
|
||||
ccr = readl(pdata->csr_base + RTC_CCR);
|
||||
if (enabled) {
|
||||
ccr &= ~RTC_CCR_MASK;
|
||||
ccr |= RTC_CCR_IE;
|
||||
} else {
|
||||
ccr &= ~RTC_CCR_IE;
|
||||
ccr |= RTC_CCR_MASK;
|
||||
}
|
||||
writel(ccr, pdata->csr_base + RTC_CCR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xgene_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
|
||||
unsigned long rtc_time;
|
||||
unsigned long alarm_time;
|
||||
|
||||
rtc_time = readl(pdata->csr_base + RTC_CCVR);
|
||||
rtc_tm_to_time(&alrm->time, &alarm_time);
|
||||
|
||||
pdata->alarm_time = alarm_time;
|
||||
writel((u32) pdata->alarm_time, pdata->csr_base + RTC_CMR);
|
||||
|
||||
xgene_rtc_alarm_irq_enable(dev, alrm->enabled);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops xgene_rtc_ops = {
|
||||
.read_time = xgene_rtc_read_time,
|
||||
.set_mmss = xgene_rtc_set_mmss,
|
||||
.read_alarm = xgene_rtc_read_alarm,
|
||||
.set_alarm = xgene_rtc_set_alarm,
|
||||
.alarm_irq_enable = xgene_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static irqreturn_t xgene_rtc_interrupt(int irq, void *id)
|
||||
{
|
||||
struct xgene_rtc_dev *pdata = (struct xgene_rtc_dev *) id;
|
||||
|
||||
/* Check if interrupt asserted */
|
||||
if (!(readl(pdata->csr_base + RTC_STAT) & RTC_STAT_BIT))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Clear interrupt */
|
||||
readl(pdata->csr_base + RTC_EOI);
|
||||
|
||||
rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int xgene_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct xgene_rtc_dev *pdata;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
int irq;
|
||||
|
||||
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, pdata);
|
||||
pdata->dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
pdata->csr_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(pdata->csr_base))
|
||||
return PTR_ERR(pdata->csr_base);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "No IRQ resource\n");
|
||||
return irq;
|
||||
}
|
||||
ret = devm_request_irq(&pdev->dev, irq, xgene_rtc_interrupt, 0,
|
||||
dev_name(&pdev->dev), pdata);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Could not request IRQ\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdata->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(pdata->clk)) {
|
||||
dev_err(&pdev->dev, "Couldn't get the clock for RTC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
clk_prepare_enable(pdata->clk);
|
||||
|
||||
/* Turn on the clock and the crystal */
|
||||
writel(RTC_CCR_EN, pdata->csr_base + RTC_CCR);
|
||||
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
|
||||
&xgene_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(pdata->rtc)) {
|
||||
clk_disable_unprepare(pdata->clk);
|
||||
return PTR_ERR(pdata->rtc);
|
||||
}
|
||||
|
||||
/* HW does not support update faster than 1 seconds */
|
||||
pdata->rtc->uie_unsupported = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xgene_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev);
|
||||
|
||||
xgene_rtc_alarm_irq_enable(&pdev->dev, 0);
|
||||
device_init_wakeup(&pdev->dev, 0);
|
||||
clk_disable_unprepare(pdata->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int xgene_rtc_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev);
|
||||
int irq;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (device_may_wakeup(&pdev->dev)) {
|
||||
if (!enable_irq_wake(irq))
|
||||
pdata->irq_wake = 1;
|
||||
} else {
|
||||
xgene_rtc_alarm_irq_enable(dev, 0);
|
||||
clk_disable(pdata->clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xgene_rtc_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev);
|
||||
int irq;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (device_may_wakeup(&pdev->dev)) {
|
||||
if (pdata->irq_wake) {
|
||||
disable_irq_wake(irq);
|
||||
pdata->irq_wake = 0;
|
||||
}
|
||||
} else {
|
||||
clk_enable(pdata->clk);
|
||||
xgene_rtc_alarm_irq_enable(dev, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(xgene_rtc_pm_ops, xgene_rtc_suspend, xgene_rtc_resume);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id xgene_rtc_of_match[] = {
|
||||
{.compatible = "apm,xgene-rtc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, xgene_rtc_of_match);
|
||||
#endif
|
||||
|
||||
static struct platform_driver xgene_rtc_driver = {
|
||||
.probe = xgene_rtc_probe,
|
||||
.remove = xgene_rtc_remove,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "xgene-rtc",
|
||||
.pm = &xgene_rtc_pm_ops,
|
||||
.of_match_table = of_match_ptr(xgene_rtc_of_match),
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(xgene_rtc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("APM X-Gene SoC RTC driver");
|
||||
MODULE_AUTHOR("Rameshwar Sahu <rsahu@apm.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -12,7 +12,7 @@
|
||||
#include "scsi_priv.h"
|
||||
|
||||
|
||||
static ctl_table scsi_table[] = {
|
||||
static struct ctl_table scsi_table[] = {
|
||||
{ .procname = "logging_level",
|
||||
.data = &scsi_logging_level,
|
||||
.maxlen = sizeof(scsi_logging_level),
|
||||
@ -21,14 +21,14 @@ static ctl_table scsi_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static ctl_table scsi_dir_table[] = {
|
||||
static struct ctl_table scsi_dir_table[] = {
|
||||
{ .procname = "scsi",
|
||||
.mode = 0555,
|
||||
.child = scsi_table },
|
||||
{ }
|
||||
};
|
||||
|
||||
static ctl_table scsi_root_table[] = {
|
||||
static struct ctl_table scsi_root_table[] = {
|
||||
{ .procname = "dev",
|
||||
.mode = 0555,
|
||||
.child = scsi_dir_table },
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/irq_regs.h>
|
||||
@ -510,9 +511,9 @@ void __handle_sysrq(int key, bool check_mask)
|
||||
struct sysrq_key_op *op_p;
|
||||
int orig_log_level;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&sysrq_key_table_lock, flags);
|
||||
rcu_sysrq_start();
|
||||
rcu_read_lock();
|
||||
/*
|
||||
* Raise the apparent loglevel to maximum so that the sysrq header
|
||||
* is shown to provide the user with positive feedback. We do not
|
||||
@ -554,7 +555,8 @@ void __handle_sysrq(int key, bool check_mask)
|
||||
printk("\n");
|
||||
console_loglevel = orig_log_level;
|
||||
}
|
||||
spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
|
||||
rcu_read_unlock();
|
||||
rcu_sysrq_end();
|
||||
}
|
||||
|
||||
void handle_sysrq(int key)
|
||||
@ -1043,16 +1045,23 @@ static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
|
||||
struct sysrq_key_op *remove_op_p)
|
||||
{
|
||||
int retval;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&sysrq_key_table_lock, flags);
|
||||
spin_lock(&sysrq_key_table_lock);
|
||||
if (__sysrq_get_key_op(key) == remove_op_p) {
|
||||
__sysrq_put_key_op(key, insert_op_p);
|
||||
retval = 0;
|
||||
} else {
|
||||
retval = -1;
|
||||
}
|
||||
spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
|
||||
spin_unlock(&sysrq_key_table_lock);
|
||||
|
||||
/*
|
||||
* A concurrent __handle_sysrq either got the old op or the new op.
|
||||
* Wait for it to go away before returning, so the code for an old
|
||||
* op is not freed (eg. on module unload) while it is in use.
|
||||
*/
|
||||
synchronize_rcu();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
#ifdef pr_fmt
|
||||
#undef pr_fmt
|
||||
#endif
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/buffer_head.h>
|
||||
@ -206,7 +212,7 @@ affs_set_blocksize(struct super_block *sb, int size)
|
||||
static inline struct buffer_head *
|
||||
affs_bread(struct super_block *sb, int block)
|
||||
{
|
||||
pr_debug("affs_bread: %d\n", block);
|
||||
pr_debug("%s: %d\n", __func__, block);
|
||||
if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size)
|
||||
return sb_bread(sb, block);
|
||||
return NULL;
|
||||
@ -214,7 +220,7 @@ affs_bread(struct super_block *sb, int block)
|
||||
static inline struct buffer_head *
|
||||
affs_getblk(struct super_block *sb, int block)
|
||||
{
|
||||
pr_debug("affs_getblk: %d\n", block);
|
||||
pr_debug("%s: %d\n", __func__, block);
|
||||
if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size)
|
||||
return sb_getblk(sb, block);
|
||||
return NULL;
|
||||
@ -223,7 +229,7 @@ static inline struct buffer_head *
|
||||
affs_getzeroblk(struct super_block *sb, int block)
|
||||
{
|
||||
struct buffer_head *bh;
|
||||
pr_debug("affs_getzeroblk: %d\n", block);
|
||||
pr_debug("%s: %d\n", __func__, block);
|
||||
if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size) {
|
||||
bh = sb_getblk(sb, block);
|
||||
lock_buffer(bh);
|
||||
@ -238,7 +244,7 @@ static inline struct buffer_head *
|
||||
affs_getemptyblk(struct super_block *sb, int block)
|
||||
{
|
||||
struct buffer_head *bh;
|
||||
pr_debug("affs_getemptyblk: %d\n", block);
|
||||
pr_debug("%s: %d\n", __func__, block);
|
||||
if (block >= AFFS_SB(sb)->s_reserved && block < AFFS_SB(sb)->s_partition_size) {
|
||||
bh = sb_getblk(sb, block);
|
||||
wait_on_buffer(bh);
|
||||
@ -251,7 +257,7 @@ static inline void
|
||||
affs_brelse(struct buffer_head *bh)
|
||||
{
|
||||
if (bh)
|
||||
pr_debug("affs_brelse: %lld\n", (long long) bh->b_blocknr);
|
||||
pr_debug("%s: %lld\n", __func__, (long long) bh->b_blocknr);
|
||||
brelse(bh);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ affs_insert_hash(struct inode *dir, struct buffer_head *bh)
|
||||
ino = bh->b_blocknr;
|
||||
offset = affs_hash_name(sb, AFFS_TAIL(sb, bh)->name + 1, AFFS_TAIL(sb, bh)->name[0]);
|
||||
|
||||
pr_debug("AFFS: insert_hash(dir=%u, ino=%d)\n", (u32)dir->i_ino, ino);
|
||||
pr_debug("%s(dir=%u, ino=%d)\n", __func__, (u32)dir->i_ino, ino);
|
||||
|
||||
dir_bh = affs_bread(sb, dir->i_ino);
|
||||
if (!dir_bh)
|
||||
@ -84,7 +84,8 @@ affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh)
|
||||
sb = dir->i_sb;
|
||||
rem_ino = rem_bh->b_blocknr;
|
||||
offset = affs_hash_name(sb, AFFS_TAIL(sb, rem_bh)->name+1, AFFS_TAIL(sb, rem_bh)->name[0]);
|
||||
pr_debug("AFFS: remove_hash(dir=%d, ino=%d, hashval=%d)\n", (u32)dir->i_ino, rem_ino, offset);
|
||||
pr_debug("%s(dir=%d, ino=%d, hashval=%d)\n",
|
||||
__func__, (u32)dir->i_ino, rem_ino, offset);
|
||||
|
||||
bh = affs_bread(sb, dir->i_ino);
|
||||
if (!bh)
|
||||
@ -147,7 +148,7 @@ affs_remove_link(struct dentry *dentry)
|
||||
u32 link_ino, ino;
|
||||
int retval;
|
||||
|
||||
pr_debug("AFFS: remove_link(key=%ld)\n", inode->i_ino);
|
||||
pr_debug("%s(key=%ld)\n", __func__, inode->i_ino);
|
||||
retval = -EIO;
|
||||
bh = affs_bread(sb, inode->i_ino);
|
||||
if (!bh)
|
||||
@ -279,7 +280,7 @@ affs_remove_header(struct dentry *dentry)
|
||||
if (!inode)
|
||||
goto done;
|
||||
|
||||
pr_debug("AFFS: remove_header(key=%ld)\n", inode->i_ino);
|
||||
pr_debug("%s(key=%ld)\n", __func__, inode->i_ino);
|
||||
retval = -EIO;
|
||||
bh = affs_bread(sb, (u32)(long)dentry->d_fsdata);
|
||||
if (!bh)
|
||||
@ -451,10 +452,10 @@ affs_error(struct super_block *sb, const char *function, const char *fmt, ...)
|
||||
vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args);
|
||||
va_end(args);
|
||||
|
||||
printk(KERN_CRIT "AFFS error (device %s): %s(): %s\n", sb->s_id,
|
||||
pr_crit("error (device %s): %s(): %s\n", sb->s_id,
|
||||
function,ErrorBuffer);
|
||||
if (!(sb->s_flags & MS_RDONLY))
|
||||
printk(KERN_WARNING "AFFS: Remounting filesystem read-only\n");
|
||||
pr_warn("Remounting filesystem read-only\n");
|
||||
sb->s_flags |= MS_RDONLY;
|
||||
}
|
||||
|
||||
@ -467,7 +468,7 @@ affs_warning(struct super_block *sb, const char *function, const char *fmt, ...)
|
||||
vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args);
|
||||
va_end(args);
|
||||
|
||||
printk(KERN_WARNING "AFFS warning (device %s): %s(): %s\n", sb->s_id,
|
||||
pr_warn("(device %s): %s(): %s\n", sb->s_id,
|
||||
function,ErrorBuffer);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ affs_count_free_blocks(struct super_block *sb)
|
||||
u32 free;
|
||||
int i;
|
||||
|
||||
pr_debug("AFFS: count_free_blocks()\n");
|
||||
pr_debug("%s()\n", __func__);
|
||||
|
||||
if (sb->s_flags & MS_RDONLY)
|
||||
return 0;
|
||||
@ -43,7 +43,7 @@ affs_free_block(struct super_block *sb, u32 block)
|
||||
u32 blk, bmap, bit, mask, tmp;
|
||||
__be32 *data;
|
||||
|
||||
pr_debug("AFFS: free_block(%u)\n", block);
|
||||
pr_debug("%s(%u)\n", __func__, block);
|
||||
|
||||
if (block > sbi->s_partition_size)
|
||||
goto err_range;
|
||||
@ -125,7 +125,7 @@ affs_alloc_block(struct inode *inode, u32 goal)
|
||||
sb = inode->i_sb;
|
||||
sbi = AFFS_SB(sb);
|
||||
|
||||
pr_debug("AFFS: balloc(inode=%lu,goal=%u): ", inode->i_ino, goal);
|
||||
pr_debug("balloc(inode=%lu,goal=%u): ", inode->i_ino, goal);
|
||||
|
||||
if (AFFS_I(inode)->i_pa_cnt) {
|
||||
pr_debug("%d\n", AFFS_I(inode)->i_lastalloc+1);
|
||||
@ -254,8 +254,7 @@ int affs_init_bitmap(struct super_block *sb, int *flags)
|
||||
return 0;
|
||||
|
||||
if (!AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag) {
|
||||
printk(KERN_NOTICE "AFFS: Bitmap invalid - mounting %s read only\n",
|
||||
sb->s_id);
|
||||
pr_notice("Bitmap invalid - mounting %s read only\n", sb->s_id);
|
||||
*flags |= MS_RDONLY;
|
||||
return 0;
|
||||
}
|
||||
@ -268,7 +267,7 @@ int affs_init_bitmap(struct super_block *sb, int *flags)
|
||||
size = sbi->s_bmap_count * sizeof(*bm);
|
||||
bm = sbi->s_bitmap = kzalloc(size, GFP_KERNEL);
|
||||
if (!sbi->s_bitmap) {
|
||||
printk(KERN_ERR "AFFS: Bitmap allocation failed\n");
|
||||
pr_err("Bitmap allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -282,17 +281,17 @@ int affs_init_bitmap(struct super_block *sb, int *flags)
|
||||
bm->bm_key = be32_to_cpu(bmap_blk[blk]);
|
||||
bh = affs_bread(sb, bm->bm_key);
|
||||
if (!bh) {
|
||||
printk(KERN_ERR "AFFS: Cannot read bitmap\n");
|
||||
pr_err("Cannot read bitmap\n");
|
||||
res = -EIO;
|
||||
goto out;
|
||||
}
|
||||
if (affs_checksum_block(sb, bh)) {
|
||||
printk(KERN_WARNING "AFFS: Bitmap %u invalid - mounting %s read only.\n",
|
||||
bm->bm_key, sb->s_id);
|
||||
pr_warn("Bitmap %u invalid - mounting %s read only.\n",
|
||||
bm->bm_key, sb->s_id);
|
||||
*flags |= MS_RDONLY;
|
||||
goto out;
|
||||
}
|
||||
pr_debug("AFFS: read bitmap block %d: %d\n", blk, bm->bm_key);
|
||||
pr_debug("read bitmap block %d: %d\n", blk, bm->bm_key);
|
||||
bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4);
|
||||
|
||||
/* Don't try read the extension if this is the last block,
|
||||
@ -304,7 +303,7 @@ int affs_init_bitmap(struct super_block *sb, int *flags)
|
||||
affs_brelse(bmap_bh);
|
||||
bmap_bh = affs_bread(sb, be32_to_cpu(bmap_blk[blk]));
|
||||
if (!bmap_bh) {
|
||||
printk(KERN_ERR "AFFS: Cannot read bitmap extension\n");
|
||||
pr_err("Cannot read bitmap extension\n");
|
||||
res = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
@ -54,8 +54,8 @@ affs_readdir(struct file *file, struct dir_context *ctx)
|
||||
u32 ino;
|
||||
int error = 0;
|
||||
|
||||
pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",
|
||||
inode->i_ino, (unsigned long)ctx->pos);
|
||||
pr_debug("%s(ino=%lu,f_pos=%lx)\n",
|
||||
__func__, inode->i_ino, (unsigned long)ctx->pos);
|
||||
|
||||
if (ctx->pos < 2) {
|
||||
file->private_data = (void *)0;
|
||||
@ -81,7 +81,7 @@ affs_readdir(struct file *file, struct dir_context *ctx)
|
||||
*/
|
||||
ino = (u32)(long)file->private_data;
|
||||
if (ino && file->f_version == inode->i_version) {
|
||||
pr_debug("AFFS: readdir() left off=%d\n", ino);
|
||||
pr_debug("readdir() left off=%d\n", ino);
|
||||
goto inside;
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ inside:
|
||||
|
||||
namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], (u8)30);
|
||||
name = AFFS_TAIL(sb, fh_bh)->name + 1;
|
||||
pr_debug("AFFS: readdir(): dir_emit(\"%.*s\", "
|
||||
pr_debug("readdir(): dir_emit(\"%.*s\", "
|
||||
"ino=%u), hash=%d, f_pos=%x\n",
|
||||
namelen, name, ino, hash_pos, (u32)ctx->pos);
|
||||
|
||||
|
@ -45,7 +45,7 @@ const struct inode_operations affs_file_inode_operations = {
|
||||
static int
|
||||
affs_file_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
pr_debug("AFFS: open(%lu,%d)\n",
|
||||
pr_debug("open(%lu,%d)\n",
|
||||
inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
|
||||
atomic_inc(&AFFS_I(inode)->i_opencnt);
|
||||
return 0;
|
||||
@ -54,7 +54,7 @@ affs_file_open(struct inode *inode, struct file *filp)
|
||||
static int
|
||||
affs_file_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
pr_debug("AFFS: release(%lu, %d)\n",
|
||||
pr_debug("release(%lu, %d)\n",
|
||||
inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
|
||||
|
||||
if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) {
|
||||
@ -324,7 +324,8 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul
|
||||
struct buffer_head *ext_bh;
|
||||
u32 ext;
|
||||
|
||||
pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block);
|
||||
pr_debug("%s(%u, %lu)\n",
|
||||
__func__, (u32)inode->i_ino, (unsigned long)block);
|
||||
|
||||
BUG_ON(block > (sector_t)0x7fffffffUL);
|
||||
|
||||
@ -498,34 +499,36 @@ affs_getemptyblk_ino(struct inode *inode, int block)
|
||||
}
|
||||
|
||||
static int
|
||||
affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsigned to)
|
||||
affs_do_readpage_ofs(struct page *page, unsigned to)
|
||||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct buffer_head *bh;
|
||||
char *data;
|
||||
unsigned pos = 0;
|
||||
u32 bidx, boff, bsize;
|
||||
u32 tmp;
|
||||
|
||||
pr_debug("AFFS: read_page(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to);
|
||||
BUG_ON(from > to || to > PAGE_CACHE_SIZE);
|
||||
pr_debug("%s(%u, %ld, 0, %d)\n", __func__, (u32)inode->i_ino,
|
||||
page->index, to);
|
||||
BUG_ON(to > PAGE_CACHE_SIZE);
|
||||
kmap(page);
|
||||
data = page_address(page);
|
||||
bsize = AFFS_SB(sb)->s_data_blksize;
|
||||
tmp = (page->index << PAGE_CACHE_SHIFT) + from;
|
||||
tmp = page->index << PAGE_CACHE_SHIFT;
|
||||
bidx = tmp / bsize;
|
||||
boff = tmp % bsize;
|
||||
|
||||
while (from < to) {
|
||||
while (pos < to) {
|
||||
bh = affs_bread_ino(inode, bidx, 0);
|
||||
if (IS_ERR(bh))
|
||||
return PTR_ERR(bh);
|
||||
tmp = min(bsize - boff, to - from);
|
||||
BUG_ON(from + tmp > to || tmp > bsize);
|
||||
memcpy(data + from, AFFS_DATA(bh) + boff, tmp);
|
||||
tmp = min(bsize - boff, to - pos);
|
||||
BUG_ON(pos + tmp > to || tmp > bsize);
|
||||
memcpy(data + pos, AFFS_DATA(bh) + boff, tmp);
|
||||
affs_brelse(bh);
|
||||
bidx++;
|
||||
from += tmp;
|
||||
pos += tmp;
|
||||
boff = 0;
|
||||
}
|
||||
flush_dcache_page(page);
|
||||
@ -542,7 +545,7 @@ affs_extent_file_ofs(struct inode *inode, u32 newsize)
|
||||
u32 size, bsize;
|
||||
u32 tmp;
|
||||
|
||||
pr_debug("AFFS: extent_file(%u, %d)\n", (u32)inode->i_ino, newsize);
|
||||
pr_debug("%s(%u, %d)\n", __func__, (u32)inode->i_ino, newsize);
|
||||
bsize = AFFS_SB(sb)->s_data_blksize;
|
||||
bh = NULL;
|
||||
size = AFFS_I(inode)->mmu_private;
|
||||
@ -608,14 +611,14 @@ affs_readpage_ofs(struct file *file, struct page *page)
|
||||
u32 to;
|
||||
int err;
|
||||
|
||||
pr_debug("AFFS: read_page(%u, %ld)\n", (u32)inode->i_ino, page->index);
|
||||
pr_debug("%s(%u, %ld)\n", __func__, (u32)inode->i_ino, page->index);
|
||||
to = PAGE_CACHE_SIZE;
|
||||
if (((page->index + 1) << PAGE_CACHE_SHIFT) > inode->i_size) {
|
||||
to = inode->i_size & ~PAGE_CACHE_MASK;
|
||||
memset(page_address(page) + to, 0, PAGE_CACHE_SIZE - to);
|
||||
}
|
||||
|
||||
err = affs_do_readpage_ofs(file, page, 0, to);
|
||||
err = affs_do_readpage_ofs(page, to);
|
||||
if (!err)
|
||||
SetPageUptodate(page);
|
||||
unlock_page(page);
|
||||
@ -631,7 +634,8 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping
|
||||
pgoff_t index;
|
||||
int err = 0;
|
||||
|
||||
pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
|
||||
pr_debug("%s(%u, %llu, %llu)\n", __func__, (u32)inode->i_ino,
|
||||
(unsigned long long)pos, (unsigned long long)pos + len);
|
||||
if (pos > AFFS_I(inode)->mmu_private) {
|
||||
/* XXX: this probably leaves a too-big i_size in case of
|
||||
* failure. Should really be updating i_size at write_end time
|
||||
@ -651,7 +655,7 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping
|
||||
return 0;
|
||||
|
||||
/* XXX: inefficient but safe in the face of short writes */
|
||||
err = affs_do_readpage_ofs(file, page, 0, PAGE_CACHE_SIZE);
|
||||
err = affs_do_readpage_ofs(page, PAGE_CACHE_SIZE);
|
||||
if (err) {
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
@ -680,7 +684,9 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
|
||||
* due to write_begin.
|
||||
*/
|
||||
|
||||
pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
|
||||
pr_debug("%s(%u, %llu, %llu)\n",
|
||||
__func__, (u32)inode->i_ino, (unsigned long long)pos,
|
||||
(unsigned long long)pos + len);
|
||||
bsize = AFFS_SB(sb)->s_data_blksize;
|
||||
data = page_address(page);
|
||||
|
||||
@ -802,7 +808,7 @@ affs_free_prealloc(struct inode *inode)
|
||||
{
|
||||
struct super_block *sb = inode->i_sb;
|
||||
|
||||
pr_debug("AFFS: free_prealloc(ino=%lu)\n", inode->i_ino);
|
||||
pr_debug("free_prealloc(ino=%lu)\n", inode->i_ino);
|
||||
|
||||
while (AFFS_I(inode)->i_pa_cnt) {
|
||||
AFFS_I(inode)->i_pa_cnt--;
|
||||
@ -822,7 +828,7 @@ affs_truncate(struct inode *inode)
|
||||
struct buffer_head *ext_bh;
|
||||
int i;
|
||||
|
||||
pr_debug("AFFS: truncate(inode=%d, oldsize=%u, newsize=%u)\n",
|
||||
pr_debug("truncate(inode=%d, oldsize=%u, newsize=%u)\n",
|
||||
(u32)inode->i_ino, (u32)AFFS_I(inode)->mmu_private, (u32)inode->i_size);
|
||||
|
||||
last_blk = 0;
|
||||
|
@ -34,7 +34,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
|
||||
if (!(inode->i_state & I_NEW))
|
||||
return inode;
|
||||
|
||||
pr_debug("AFFS: affs_iget(%lu)\n", inode->i_ino);
|
||||
pr_debug("affs_iget(%lu)\n", inode->i_ino);
|
||||
|
||||
block = inode->i_ino;
|
||||
bh = affs_bread(sb, block);
|
||||
@ -175,7 +175,7 @@ affs_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
|
||||
pr_debug("AFFS: write_inode(%lu)\n",inode->i_ino);
|
||||
pr_debug("write_inode(%lu)\n", inode->i_ino);
|
||||
|
||||
if (!inode->i_nlink)
|
||||
// possibly free block
|
||||
@ -220,7 +220,7 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
|
||||
pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
|
||||
pr_debug("notify_change(%lu,0x%x)\n", inode->i_ino, attr->ia_valid);
|
||||
|
||||
error = inode_change_ok(inode,attr);
|
||||
if (error)
|
||||
@ -258,7 +258,8 @@ void
|
||||
affs_evict_inode(struct inode *inode)
|
||||
{
|
||||
unsigned long cache_page;
|
||||
pr_debug("AFFS: evict_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
|
||||
pr_debug("evict_inode(ino=%lu, nlink=%u)\n",
|
||||
inode->i_ino, inode->i_nlink);
|
||||
truncate_inode_pages_final(&inode->i_data);
|
||||
|
||||
if (!inode->i_nlink) {
|
||||
@ -271,7 +272,7 @@ affs_evict_inode(struct inode *inode)
|
||||
affs_free_prealloc(inode);
|
||||
cache_page = (unsigned long)AFFS_I(inode)->i_lc;
|
||||
if (cache_page) {
|
||||
pr_debug("AFFS: freeing ext cache\n");
|
||||
pr_debug("freeing ext cache\n");
|
||||
AFFS_I(inode)->i_lc = NULL;
|
||||
AFFS_I(inode)->i_ac = NULL;
|
||||
free_page(cache_page);
|
||||
@ -350,7 +351,8 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3
|
||||
u32 block = 0;
|
||||
int retval;
|
||||
|
||||
pr_debug("AFFS: add_entry(dir=%u, inode=%u, \"%*s\", type=%d)\n", (u32)dir->i_ino,
|
||||
pr_debug("%s(dir=%u, inode=%u, \"%*s\", type=%d)\n",
|
||||
__func__, (u32)dir->i_ino,
|
||||
(u32)inode->i_ino, (int)dentry->d_name.len, dentry->d_name.name, type);
|
||||
|
||||
retval = -EIO;
|
||||
|
@ -190,7 +190,8 @@ affs_find_entry(struct inode *dir, struct dentry *dentry)
|
||||
toupper_t toupper = affs_get_toupper(sb);
|
||||
u32 key;
|
||||
|
||||
pr_debug("AFFS: find_entry(\"%.*s\")\n", (int)dentry->d_name.len, dentry->d_name.name);
|
||||
pr_debug("%s(\"%.*s\")\n",
|
||||
__func__, (int)dentry->d_name.len, dentry->d_name.name);
|
||||
|
||||
bh = affs_bread(sb, dir->i_ino);
|
||||
if (!bh)
|
||||
@ -218,7 +219,8 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
struct buffer_head *bh;
|
||||
struct inode *inode = NULL;
|
||||
|
||||
pr_debug("AFFS: lookup(\"%.*s\")\n",(int)dentry->d_name.len,dentry->d_name.name);
|
||||
pr_debug("%s(\"%.*s\")\n",
|
||||
__func__, (int)dentry->d_name.len, dentry->d_name.name);
|
||||
|
||||
affs_lock_dir(dir);
|
||||
bh = affs_find_entry(dir, dentry);
|
||||
@ -248,9 +250,9 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
|
||||
int
|
||||
affs_unlink(struct inode *dir, struct dentry *dentry)
|
||||
{
|
||||
pr_debug("AFFS: unlink(dir=%d, %lu \"%.*s\")\n", (u32)dir->i_ino,
|
||||
dentry->d_inode->i_ino,
|
||||
(int)dentry->d_name.len, dentry->d_name.name);
|
||||
pr_debug("%s(dir=%d, %lu \"%.*s\")\n",
|
||||
__func__, (u32)dir->i_ino, dentry->d_inode->i_ino,
|
||||
(int)dentry->d_name.len, dentry->d_name.name);
|
||||
|
||||
return affs_remove_header(dentry);
|
||||
}
|
||||
@ -262,7 +264,8 @@ affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
|
||||
struct inode *inode;
|
||||
int error;
|
||||
|
||||
pr_debug("AFFS: create(%lu,\"%.*s\",0%ho)\n",dir->i_ino,(int)dentry->d_name.len,
|
||||
pr_debug("%s(%lu,\"%.*s\",0%ho)\n",
|
||||
__func__, dir->i_ino, (int)dentry->d_name.len,
|
||||
dentry->d_name.name,mode);
|
||||
|
||||
inode = affs_new_inode(dir);
|
||||
@ -291,8 +294,9 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
struct inode *inode;
|
||||
int error;
|
||||
|
||||
pr_debug("AFFS: mkdir(%lu,\"%.*s\",0%ho)\n",dir->i_ino,
|
||||
(int)dentry->d_name.len,dentry->d_name.name,mode);
|
||||
pr_debug("%s(%lu,\"%.*s\",0%ho)\n",
|
||||
__func__, dir->i_ino, (int)dentry->d_name.len,
|
||||
dentry->d_name.name, mode);
|
||||
|
||||
inode = affs_new_inode(dir);
|
||||
if (!inode)
|
||||
@ -317,8 +321,8 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
int
|
||||
affs_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
{
|
||||
pr_debug("AFFS: rmdir(dir=%u, %lu \"%.*s\")\n", (u32)dir->i_ino,
|
||||
dentry->d_inode->i_ino,
|
||||
pr_debug("%s(dir=%u, %lu \"%.*s\")\n",
|
||||
__func__, (u32)dir->i_ino, dentry->d_inode->i_ino,
|
||||
(int)dentry->d_name.len, dentry->d_name.name);
|
||||
|
||||
return affs_remove_header(dentry);
|
||||
@ -334,8 +338,9 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
|
||||
int i, maxlen, error;
|
||||
char c, lc;
|
||||
|
||||
pr_debug("AFFS: symlink(%lu,\"%.*s\" -> \"%s\")\n",dir->i_ino,
|
||||
(int)dentry->d_name.len,dentry->d_name.name,symname);
|
||||
pr_debug("%s(%lu,\"%.*s\" -> \"%s\")\n",
|
||||
__func__, dir->i_ino, (int)dentry->d_name.len,
|
||||
dentry->d_name.name, symname);
|
||||
|
||||
maxlen = AFFS_SB(sb)->s_hashsize * sizeof(u32) - 1;
|
||||
inode = affs_new_inode(dir);
|
||||
@ -404,7 +409,8 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
||||
{
|
||||
struct inode *inode = old_dentry->d_inode;
|
||||
|
||||
pr_debug("AFFS: link(%u, %u, \"%.*s\")\n", (u32)inode->i_ino, (u32)dir->i_ino,
|
||||
pr_debug("%s(%u, %u, \"%.*s\")\n",
|
||||
__func__, (u32)inode->i_ino, (u32)dir->i_ino,
|
||||
(int)dentry->d_name.len,dentry->d_name.name);
|
||||
|
||||
return affs_add_entry(dir, inode, dentry, ST_LINKFILE);
|
||||
@ -418,9 +424,10 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct buffer_head *bh = NULL;
|
||||
int retval;
|
||||
|
||||
pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n",
|
||||
(u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name,
|
||||
(u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name);
|
||||
pr_debug("%s(old=%u,\"%*s\" to new=%u,\"%*s\")\n",
|
||||
__func__, (u32)old_dir->i_ino, (int)old_dentry->d_name.len,
|
||||
old_dentry->d_name.name, (u32)new_dir->i_ino,
|
||||
(int)new_dentry->d_name.len, new_dentry->d_name.name);
|
||||
|
||||
retval = affs_check_name(new_dentry->d_name.name,
|
||||
new_dentry->d_name.len,
|
||||
|
@ -46,7 +46,7 @@ static void
|
||||
affs_put_super(struct super_block *sb)
|
||||
{
|
||||
struct affs_sb_info *sbi = AFFS_SB(sb);
|
||||
pr_debug("AFFS: put_super()\n");
|
||||
pr_debug("%s()\n", __func__);
|
||||
|
||||
cancel_delayed_work_sync(&sbi->sb_work);
|
||||
}
|
||||
@ -220,7 +220,7 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved,
|
||||
return 0;
|
||||
if (n != 512 && n != 1024 && n != 2048
|
||||
&& n != 4096) {
|
||||
printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
|
||||
pr_warn("Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
|
||||
return 0;
|
||||
}
|
||||
*blocksize = n;
|
||||
@ -285,8 +285,8 @@ parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved,
|
||||
/* Silently ignore the quota options */
|
||||
break;
|
||||
default:
|
||||
printk("AFFS: Unrecognized mount option \"%s\" "
|
||||
"or missing value\n", p);
|
||||
pr_warn("Unrecognized mount option \"%s\" or missing value\n",
|
||||
p);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -319,7 +319,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
|
||||
save_mount_options(sb, data);
|
||||
|
||||
pr_debug("AFFS: read_super(%s)\n",data ? (const char *)data : "no options");
|
||||
pr_debug("read_super(%s)\n", data ? (const char *)data : "no options");
|
||||
|
||||
sb->s_magic = AFFS_SUPER_MAGIC;
|
||||
sb->s_op = &affs_sops;
|
||||
@ -339,7 +339,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
|
||||
&blocksize,&sbi->s_prefix,
|
||||
sbi->s_volume, &mount_flags)) {
|
||||
printk(KERN_ERR "AFFS: Error parsing options\n");
|
||||
pr_err("Error parsing options\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* N.B. after this point s_prefix must be released */
|
||||
@ -356,7 +356,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
*/
|
||||
|
||||
size = sb->s_bdev->bd_inode->i_size >> 9;
|
||||
pr_debug("AFFS: initial blocksize=%d, #blocks=%d\n", 512, size);
|
||||
pr_debug("initial blocksize=%d, #blocks=%d\n", 512, size);
|
||||
|
||||
affs_set_blocksize(sb, PAGE_SIZE);
|
||||
/* Try to find root block. Its location depends on the block size. */
|
||||
@ -371,7 +371,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
sbi->s_root_block = root_block;
|
||||
if (root_block < 0)
|
||||
sbi->s_root_block = (reserved + size - 1) / 2;
|
||||
pr_debug("AFFS: setting blocksize to %d\n", blocksize);
|
||||
pr_debug("setting blocksize to %d\n", blocksize);
|
||||
affs_set_blocksize(sb, blocksize);
|
||||
sbi->s_partition_size = size;
|
||||
|
||||
@ -386,7 +386,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
* block behind the calculated one. So we check this one, too.
|
||||
*/
|
||||
for (num_bm = 0; num_bm < 2; num_bm++) {
|
||||
pr_debug("AFFS: Dev %s, trying root=%u, bs=%d, "
|
||||
pr_debug("Dev %s, trying root=%u, bs=%d, "
|
||||
"size=%d, reserved=%d\n",
|
||||
sb->s_id,
|
||||
sbi->s_root_block + num_bm,
|
||||
@ -407,8 +407,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
}
|
||||
}
|
||||
if (!silent)
|
||||
printk(KERN_ERR "AFFS: No valid root block on device %s\n",
|
||||
sb->s_id);
|
||||
pr_err("No valid root block on device %s\n", sb->s_id);
|
||||
return -EINVAL;
|
||||
|
||||
/* N.B. after this point bh must be released */
|
||||
@ -420,7 +419,7 @@ got_root:
|
||||
/* Find out which kind of FS we have */
|
||||
boot_bh = sb_bread(sb, 0);
|
||||
if (!boot_bh) {
|
||||
printk(KERN_ERR "AFFS: Cannot read boot block\n");
|
||||
pr_err("Cannot read boot block\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(sig, boot_bh->b_data, 4);
|
||||
@ -433,8 +432,7 @@ got_root:
|
||||
*/
|
||||
if ((chksum == FS_DCFFS || chksum == MUFS_DCFFS || chksum == FS_DCOFS
|
||||
|| chksum == MUFS_DCOFS) && !(sb->s_flags & MS_RDONLY)) {
|
||||
printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n",
|
||||
sb->s_id);
|
||||
pr_notice("Dircache FS - mounting %s read only\n", sb->s_id);
|
||||
sb->s_flags |= MS_RDONLY;
|
||||
}
|
||||
switch (chksum) {
|
||||
@ -468,14 +466,14 @@ got_root:
|
||||
sb->s_flags |= MS_NOEXEC;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n",
|
||||
sb->s_id, chksum);
|
||||
pr_err("Unknown filesystem on device %s: %08X\n",
|
||||
sb->s_id, chksum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mount_flags & SF_VERBOSE) {
|
||||
u8 len = AFFS_ROOT_TAIL(sb, root_bh)->disk_name[0];
|
||||
printk(KERN_NOTICE "AFFS: Mounting volume \"%.*s\": Type=%.3s\\%c, Blocksize=%d\n",
|
||||
pr_notice("Mounting volume \"%.*s\": Type=%.3s\\%c, Blocksize=%d\n",
|
||||
len > 31 ? 31 : len,
|
||||
AFFS_ROOT_TAIL(sb, root_bh)->disk_name + 1,
|
||||
sig, sig[3] + '0', blocksize);
|
||||
@ -506,11 +504,11 @@ got_root:
|
||||
|
||||
sb->s_root = d_make_root(root_inode);
|
||||
if (!sb->s_root) {
|
||||
printk(KERN_ERR "AFFS: Get root inode failed\n");
|
||||
pr_err("AFFS: Get root inode failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
|
||||
pr_debug("s_flags=%lX\n", sb->s_flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -530,7 +528,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
|
||||
char volume[32];
|
||||
char *prefix = NULL;
|
||||
|
||||
pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
|
||||
pr_debug("%s(flags=0x%x,opts=\"%s\")\n", __func__, *flags, data);
|
||||
|
||||
sync_filesystem(sb);
|
||||
*flags |= MS_NODIRATIME;
|
||||
@ -578,8 +576,9 @@ affs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
int free;
|
||||
u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
|
||||
|
||||
pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",AFFS_SB(sb)->s_partition_size,
|
||||
AFFS_SB(sb)->s_reserved);
|
||||
pr_debug("%s() partsize=%d, reserved=%d\n",
|
||||
__func__, AFFS_SB(sb)->s_partition_size,
|
||||
AFFS_SB(sb)->s_reserved);
|
||||
|
||||
free = affs_count_free_blocks(sb);
|
||||
buf->f_type = AFFS_SUPER_MAGIC;
|
||||
|
@ -21,7 +21,7 @@ static int affs_symlink_readpage(struct file *file, struct page *page)
|
||||
char c;
|
||||
char lc;
|
||||
|
||||
pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino);
|
||||
pr_debug("follow_link(ino=%lu)\n", inode->i_ino);
|
||||
|
||||
err = -EIO;
|
||||
bh = affs_bread(inode->i_sb, inode->i_ino);
|
||||
|
@ -318,7 +318,7 @@ befs_btree_find(struct super_block *sb, befs_data_stream * ds,
|
||||
* befs_find_key - Search for a key within a node
|
||||
* @sb: Filesystem superblock
|
||||
* @node: Node to find the key within
|
||||
* @key: Keystring to search for
|
||||
* @findkey: Keystring to search for
|
||||
* @value: If key is found, the value stored with the key is put here
|
||||
*
|
||||
* finds exact match if one exists, and returns BEFS_BT_MATCH
|
||||
@ -405,7 +405,7 @@ befs_find_key(struct super_block *sb, befs_btree_node * node,
|
||||
* Heres how it works: Key_no is the index of the key/value pair to
|
||||
* return in keybuf/value.
|
||||
* Bufsize is the size of keybuf (BEFS_NAME_LEN+1 is a good size). Keysize is
|
||||
* the number of charecters in the key (just a convenience).
|
||||
* the number of characters in the key (just a convenience).
|
||||
*
|
||||
* Algorithm:
|
||||
* Get the first leafnode of the tree. See if the requested key is in that
|
||||
@ -502,12 +502,11 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds,
|
||||
"for key of size %d", __func__, bufsize, keylen);
|
||||
brelse(this_node->bh);
|
||||
goto error_alloc;
|
||||
};
|
||||
}
|
||||
|
||||
strncpy(keybuf, keystart, keylen);
|
||||
strlcpy(keybuf, keystart, keylen + 1);
|
||||
*value = fs64_to_cpu(sb, valarray[cur_key]);
|
||||
*keysize = keylen;
|
||||
keybuf[keylen] = '\0';
|
||||
|
||||
befs_debug(sb, "Read [%llu,%d]: Key \"%.*s\", Value %llu", node_off,
|
||||
cur_key, keylen, keybuf, *value);
|
||||
@ -707,7 +706,7 @@ befs_bt_get_key(struct super_block *sb, befs_btree_node * node,
|
||||
* @key1: pointer to the first key to be compared
|
||||
* @keylen1: length in bytes of key1
|
||||
* @key2: pointer to the second key to be compared
|
||||
* @kelen2: length in bytes of key2
|
||||
* @keylen2: length in bytes of key2
|
||||
*
|
||||
* Returns 0 if @key1 and @key2 are equal.
|
||||
* Returns >0 if @key1 is greater.
|
||||
|
@ -116,7 +116,7 @@ befs_fblock2brun(struct super_block *sb, befs_data_stream * data,
|
||||
* befs_read_lsmylink - read long symlink from datastream.
|
||||
* @sb: Filesystem superblock
|
||||
* @ds: Datastrem to read from
|
||||
* @buf: Buffer in which to place long symlink data
|
||||
* @buff: Buffer in which to place long symlink data
|
||||
* @len: Length of the long symlink in bytes
|
||||
*
|
||||
* Returns the number of bytes read
|
||||
|
@ -133,14 +133,6 @@ befs_get_block(struct inode *inode, sector_t block,
|
||||
|
||||
befs_debug(sb, "---> befs_get_block() for inode %lu, block %ld",
|
||||
(unsigned long)inode->i_ino, (long)block);
|
||||
|
||||
if (block < 0) {
|
||||
befs_error(sb, "befs_get_block() was asked for a block "
|
||||
"number less than zero: block %ld in inode %lu",
|
||||
(long)block, (unsigned long)inode->i_ino);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (create) {
|
||||
befs_error(sb, "befs_get_block() was asked to write to "
|
||||
"block %ld in inode %lu", (long)block,
|
||||
@ -396,9 +388,8 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
|
||||
if (S_ISLNK(inode->i_mode) && !(befs_ino->i_flags & BEFS_LONG_SYMLINK)){
|
||||
inode->i_size = 0;
|
||||
inode->i_blocks = befs_sb->block_size / VFS_BLOCK_SIZE;
|
||||
strncpy(befs_ino->i_data.symlink, raw_inode->data.symlink,
|
||||
BEFS_SYMLINK_LEN - 1);
|
||||
befs_ino->i_data.symlink[BEFS_SYMLINK_LEN - 1] = '\0';
|
||||
strlcpy(befs_ino->i_data.symlink, raw_inode->data.symlink,
|
||||
BEFS_SYMLINK_LEN);
|
||||
} else {
|
||||
int num_blks;
|
||||
|
||||
@ -591,21 +582,21 @@ befs_utf2nls(struct super_block *sb, const char *in,
|
||||
/**
|
||||
* befs_nls2utf - Convert NLS string to utf8 encodeing
|
||||
* @sb: Superblock
|
||||
* @src: Input string buffer in NLS format
|
||||
* @srclen: Length of input string in bytes
|
||||
* @dest: The output string in UTF-8 format
|
||||
* @destlen: Length of the output buffer
|
||||
* @in: Input string buffer in NLS format
|
||||
* @in_len: Length of input string in bytes
|
||||
* @out: The output string in UTF-8 format
|
||||
* @out_len: Length of the output buffer
|
||||
*
|
||||
* Converts input string @src, which is in the format of the loaded NLS map,
|
||||
* Converts input string @in, which is in the format of the loaded NLS map,
|
||||
* into a utf8 string.
|
||||
*
|
||||
* The destination string @dest is allocated by this function and the caller is
|
||||
* The destination string @out is allocated by this function and the caller is
|
||||
* responsible for freeing it with kfree()
|
||||
*
|
||||
* On return, *@destlen is the length of @dest in bytes.
|
||||
* On return, *@out_len is the length of @out in bytes.
|
||||
*
|
||||
* On success, the return value is the number of utf8 characters written to
|
||||
* the output buffer @dest.
|
||||
* the output buffer @out.
|
||||
*
|
||||
* On Failure, a negative number coresponding to the error code is returned.
|
||||
*/
|
||||
|
@ -50,18 +50,18 @@ int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args)
|
||||
cache->brun_percent < 100);
|
||||
|
||||
if (*args) {
|
||||
kerror("'bind' command doesn't take an argument");
|
||||
pr_err("'bind' command doesn't take an argument");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cache->rootdirname) {
|
||||
kerror("No cache directory specified");
|
||||
pr_err("No cache directory specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* don't permit already bound caches to be re-bound */
|
||||
if (test_bit(CACHEFILES_READY, &cache->flags)) {
|
||||
kerror("Cache already bound");
|
||||
pr_err("Cache already bound");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@ -228,9 +228,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
|
||||
set_bit(CACHEFILES_READY, &cache->flags);
|
||||
dput(root);
|
||||
|
||||
printk(KERN_INFO "CacheFiles:"
|
||||
" File cache on %s registered\n",
|
||||
cache->cache.identifier);
|
||||
pr_info("File cache on %s registered\n", cache->cache.identifier);
|
||||
|
||||
/* check how much space the cache has */
|
||||
cachefiles_has_space(cache, 0, 0);
|
||||
@ -250,7 +248,7 @@ error_open_root:
|
||||
kmem_cache_free(cachefiles_object_jar, fsdef);
|
||||
error_root_object:
|
||||
cachefiles_end_secure(cache, saved_cred);
|
||||
kerror("Failed to register: %d", ret);
|
||||
pr_err("Failed to register: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -262,9 +260,8 @@ void cachefiles_daemon_unbind(struct cachefiles_cache *cache)
|
||||
_enter("");
|
||||
|
||||
if (test_bit(CACHEFILES_READY, &cache->flags)) {
|
||||
printk(KERN_INFO "CacheFiles:"
|
||||
" File cache on %s unregistering\n",
|
||||
cache->cache.identifier);
|
||||
pr_info("File cache on %s unregistering\n",
|
||||
cache->cache.identifier);
|
||||
|
||||
fscache_withdraw_cache(&cache->cache);
|
||||
}
|
||||
|
@ -315,8 +315,7 @@ static unsigned int cachefiles_daemon_poll(struct file *file,
|
||||
static int cachefiles_daemon_range_error(struct cachefiles_cache *cache,
|
||||
char *args)
|
||||
{
|
||||
kerror("Free space limits must be in range"
|
||||
" 0%%<=stop<cull<run<100%%");
|
||||
pr_err("Free space limits must be in range 0%%<=stop<cull<run<100%%");
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -476,12 +475,12 @@ static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
|
||||
_enter(",%s", args);
|
||||
|
||||
if (!*args) {
|
||||
kerror("Empty directory specified");
|
||||
pr_err("Empty directory specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cache->rootdirname) {
|
||||
kerror("Second cache directory specified");
|
||||
pr_err("Second cache directory specified");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
@ -504,12 +503,12 @@ static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
|
||||
_enter(",%s", args);
|
||||
|
||||
if (!*args) {
|
||||
kerror("Empty security context specified");
|
||||
pr_err("Empty security context specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cache->secctx) {
|
||||
kerror("Second security context specified");
|
||||
pr_err("Second security context specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -532,7 +531,7 @@ static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args)
|
||||
_enter(",%s", args);
|
||||
|
||||
if (!*args) {
|
||||
kerror("Empty tag specified");
|
||||
pr_err("Empty tag specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -563,12 +562,12 @@ static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
|
||||
goto inval;
|
||||
|
||||
if (!test_bit(CACHEFILES_READY, &cache->flags)) {
|
||||
kerror("cull applied to unready cache");
|
||||
pr_err("cull applied to unready cache");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
|
||||
kerror("cull applied to dead cache");
|
||||
pr_err("cull applied to dead cache");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -588,11 +587,11 @@ static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
|
||||
|
||||
notdir:
|
||||
path_put(&path);
|
||||
kerror("cull command requires dirfd to be a directory");
|
||||
pr_err("cull command requires dirfd to be a directory");
|
||||
return -ENOTDIR;
|
||||
|
||||
inval:
|
||||
kerror("cull command requires dirfd and filename");
|
||||
pr_err("cull command requires dirfd and filename");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -615,7 +614,7 @@ static int cachefiles_daemon_debug(struct cachefiles_cache *cache, char *args)
|
||||
return 0;
|
||||
|
||||
inval:
|
||||
kerror("debug command requires mask");
|
||||
pr_err("debug command requires mask");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -635,12 +634,12 @@ static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
|
||||
goto inval;
|
||||
|
||||
if (!test_bit(CACHEFILES_READY, &cache->flags)) {
|
||||
kerror("inuse applied to unready cache");
|
||||
pr_err("inuse applied to unready cache");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
|
||||
kerror("inuse applied to dead cache");
|
||||
pr_err("inuse applied to dead cache");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -660,11 +659,11 @@ static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
|
||||
|
||||
notdir:
|
||||
path_put(&path);
|
||||
kerror("inuse command requires dirfd to be a directory");
|
||||
pr_err("inuse command requires dirfd to be a directory");
|
||||
return -ENOTDIR;
|
||||
|
||||
inval:
|
||||
kerror("inuse command requires dirfd and filename");
|
||||
pr_err("inuse command requires dirfd and filename");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -146,8 +146,7 @@ static int cachefiles_lookup_object(struct fscache_object *_object)
|
||||
|
||||
if (ret < 0 && ret != -ETIMEDOUT) {
|
||||
if (ret != -ENOBUFS)
|
||||
printk(KERN_WARNING
|
||||
"CacheFiles: Lookup failed error %d\n", ret);
|
||||
pr_warn("Lookup failed error %d\n", ret);
|
||||
fscache_object_lookup_error(&object->fscache);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,13 @@
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifdef pr_fmt
|
||||
#undef pr_fmt
|
||||
#endif
|
||||
|
||||
#define pr_fmt(fmt) "CacheFiles: " fmt
|
||||
|
||||
|
||||
#include <linux/fscache-cache.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/wait.h>
|
||||
@ -245,11 +252,10 @@ extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
|
||||
/*
|
||||
* error handling
|
||||
*/
|
||||
#define kerror(FMT, ...) printk(KERN_ERR "CacheFiles: "FMT"\n", ##__VA_ARGS__)
|
||||
|
||||
#define cachefiles_io_error(___cache, FMT, ...) \
|
||||
do { \
|
||||
kerror("I/O Error: " FMT, ##__VA_ARGS__); \
|
||||
pr_err("I/O Error: " FMT, ##__VA_ARGS__); \
|
||||
fscache_io_error(&(___cache)->cache); \
|
||||
set_bit(CACHEFILES_DEAD, &(___cache)->flags); \
|
||||
} while (0)
|
||||
@ -310,8 +316,8 @@ do { \
|
||||
#define ASSERT(X) \
|
||||
do { \
|
||||
if (unlikely(!(X))) { \
|
||||
printk(KERN_ERR "\n"); \
|
||||
printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
|
||||
pr_err("\n"); \
|
||||
pr_err("Assertion failed\n"); \
|
||||
BUG(); \
|
||||
} \
|
||||
} while (0)
|
||||
@ -319,9 +325,9 @@ do { \
|
||||
#define ASSERTCMP(X, OP, Y) \
|
||||
do { \
|
||||
if (unlikely(!((X) OP (Y)))) { \
|
||||
printk(KERN_ERR "\n"); \
|
||||
printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
|
||||
printk(KERN_ERR "%lx " #OP " %lx is false\n", \
|
||||
pr_err("\n"); \
|
||||
pr_err("Assertion failed\n"); \
|
||||
pr_err("%lx " #OP " %lx is false\n", \
|
||||
(unsigned long)(X), (unsigned long)(Y)); \
|
||||
BUG(); \
|
||||
} \
|
||||
@ -330,8 +336,8 @@ do { \
|
||||
#define ASSERTIF(C, X) \
|
||||
do { \
|
||||
if (unlikely((C) && !(X))) { \
|
||||
printk(KERN_ERR "\n"); \
|
||||
printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
|
||||
pr_err("\n"); \
|
||||
pr_err("Assertion failed\n"); \
|
||||
BUG(); \
|
||||
} \
|
||||
} while (0)
|
||||
@ -339,9 +345,9 @@ do { \
|
||||
#define ASSERTIFCMP(C, X, OP, Y) \
|
||||
do { \
|
||||
if (unlikely((C) && !((X) OP (Y)))) { \
|
||||
printk(KERN_ERR "\n"); \
|
||||
printk(KERN_ERR "CacheFiles: Assertion failed\n"); \
|
||||
printk(KERN_ERR "%lx " #OP " %lx is false\n", \
|
||||
pr_err("\n"); \
|
||||
pr_err("Assertion failed\n"); \
|
||||
pr_err("%lx " #OP " %lx is false\n", \
|
||||
(unsigned long)(X), (unsigned long)(Y)); \
|
||||
BUG(); \
|
||||
} \
|
||||
|
@ -68,8 +68,7 @@ static int __init cachefiles_init(void)
|
||||
SLAB_HWCACHE_ALIGN,
|
||||
cachefiles_object_init_once);
|
||||
if (!cachefiles_object_jar) {
|
||||
printk(KERN_NOTICE
|
||||
"CacheFiles: Failed to allocate an object jar\n");
|
||||
pr_notice("Failed to allocate an object jar\n");
|
||||
goto error_object_jar;
|
||||
}
|
||||
|
||||
@ -77,7 +76,7 @@ static int __init cachefiles_init(void)
|
||||
if (ret < 0)
|
||||
goto error_proc;
|
||||
|
||||
printk(KERN_INFO "CacheFiles: Loaded\n");
|
||||
pr_info("Loaded\n");
|
||||
return 0;
|
||||
|
||||
error_proc:
|
||||
@ -85,7 +84,7 @@ error_proc:
|
||||
error_object_jar:
|
||||
misc_deregister(&cachefiles_dev);
|
||||
error_dev:
|
||||
kerror("failed to register: %d", ret);
|
||||
pr_err("failed to register: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -96,7 +95,7 @@ fs_initcall(cachefiles_init);
|
||||
*/
|
||||
static void __exit cachefiles_exit(void)
|
||||
{
|
||||
printk(KERN_INFO "CacheFiles: Unloading\n");
|
||||
pr_info("Unloading\n");
|
||||
|
||||
cachefiles_proc_cleanup();
|
||||
kmem_cache_destroy(cachefiles_object_jar);
|
||||
|
@ -35,22 +35,21 @@ void __cachefiles_printk_object(struct cachefiles_object *object,
|
||||
struct fscache_cookie *cookie;
|
||||
unsigned keylen, loop;
|
||||
|
||||
printk(KERN_ERR "%sobject: OBJ%x\n",
|
||||
prefix, object->fscache.debug_id);
|
||||
printk(KERN_ERR "%sobjstate=%s fl=%lx wbusy=%x ev=%lx[%lx]\n",
|
||||
pr_err("%sobject: OBJ%x\n", prefix, object->fscache.debug_id);
|
||||
pr_err("%sobjstate=%s fl=%lx wbusy=%x ev=%lx[%lx]\n",
|
||||
prefix, object->fscache.state->name,
|
||||
object->fscache.flags, work_busy(&object->fscache.work),
|
||||
object->fscache.events, object->fscache.event_mask);
|
||||
printk(KERN_ERR "%sops=%u inp=%u exc=%u\n",
|
||||
pr_err("%sops=%u inp=%u exc=%u\n",
|
||||
prefix, object->fscache.n_ops, object->fscache.n_in_progress,
|
||||
object->fscache.n_exclusive);
|
||||
printk(KERN_ERR "%sparent=%p\n",
|
||||
pr_err("%sparent=%p\n",
|
||||
prefix, object->fscache.parent);
|
||||
|
||||
spin_lock(&object->fscache.lock);
|
||||
cookie = object->fscache.cookie;
|
||||
if (cookie) {
|
||||
printk(KERN_ERR "%scookie=%p [pr=%p nd=%p fl=%lx]\n",
|
||||
pr_err("%scookie=%p [pr=%p nd=%p fl=%lx]\n",
|
||||
prefix,
|
||||
object->fscache.cookie,
|
||||
object->fscache.cookie->parent,
|
||||
@ -62,16 +61,16 @@ void __cachefiles_printk_object(struct cachefiles_object *object,
|
||||
else
|
||||
keylen = 0;
|
||||
} else {
|
||||
printk(KERN_ERR "%scookie=NULL\n", prefix);
|
||||
pr_err("%scookie=NULL\n", prefix);
|
||||
keylen = 0;
|
||||
}
|
||||
spin_unlock(&object->fscache.lock);
|
||||
|
||||
if (keylen) {
|
||||
printk(KERN_ERR "%skey=[%u] '", prefix, keylen);
|
||||
pr_err("%skey=[%u] '", prefix, keylen);
|
||||
for (loop = 0; loop < keylen; loop++)
|
||||
printk("%02x", keybuf[loop]);
|
||||
printk("'\n");
|
||||
pr_cont("%02x", keybuf[loop]);
|
||||
pr_cont("'\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,13 +130,11 @@ found_dentry:
|
||||
dentry);
|
||||
|
||||
if (fscache_object_is_live(&object->fscache)) {
|
||||
printk(KERN_ERR "\n");
|
||||
printk(KERN_ERR "CacheFiles: Error:"
|
||||
" Can't preemptively bury live object\n");
|
||||
pr_err("\n");
|
||||
pr_err("Error: Can't preemptively bury live object\n");
|
||||
cachefiles_printk_object(object, NULL);
|
||||
} else if (test_and_set_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) {
|
||||
printk(KERN_ERR "CacheFiles: Error:"
|
||||
" Object already preemptively buried\n");
|
||||
pr_err("Error: Object already preemptively buried\n");
|
||||
}
|
||||
|
||||
write_unlock(&cache->active_lock);
|
||||
@ -160,7 +157,7 @@ try_again:
|
||||
write_lock(&cache->active_lock);
|
||||
|
||||
if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
|
||||
printk(KERN_ERR "CacheFiles: Error: Object already active\n");
|
||||
pr_err("Error: Object already active\n");
|
||||
cachefiles_printk_object(object, NULL);
|
||||
BUG();
|
||||
}
|
||||
@ -193,9 +190,8 @@ try_again:
|
||||
* need to wait for it to be destroyed */
|
||||
wait_for_old_object:
|
||||
if (fscache_object_is_live(&object->fscache)) {
|
||||
printk(KERN_ERR "\n");
|
||||
printk(KERN_ERR "CacheFiles: Error:"
|
||||
" Unexpected object collision\n");
|
||||
pr_err("\n");
|
||||
pr_err("Error: Unexpected object collision\n");
|
||||
cachefiles_printk_object(object, xobject);
|
||||
BUG();
|
||||
}
|
||||
@ -241,9 +237,8 @@ wait_for_old_object:
|
||||
}
|
||||
|
||||
if (timeout <= 0) {
|
||||
printk(KERN_ERR "\n");
|
||||
printk(KERN_ERR "CacheFiles: Error: Overlong"
|
||||
" wait for old active object to go away\n");
|
||||
pr_err("\n");
|
||||
pr_err("Error: Overlong wait for old active object to go away\n");
|
||||
cachefiles_printk_object(object, xobject);
|
||||
goto requeue;
|
||||
}
|
||||
@ -548,7 +543,7 @@ lookup_again:
|
||||
next, next->d_inode, next->d_inode->i_ino);
|
||||
|
||||
} else if (!S_ISDIR(next->d_inode->i_mode)) {
|
||||
kerror("inode %lu is not a directory",
|
||||
pr_err("inode %lu is not a directory",
|
||||
next->d_inode->i_ino);
|
||||
ret = -ENOBUFS;
|
||||
goto error;
|
||||
@ -579,7 +574,7 @@ lookup_again:
|
||||
} else if (!S_ISDIR(next->d_inode->i_mode) &&
|
||||
!S_ISREG(next->d_inode->i_mode)
|
||||
) {
|
||||
kerror("inode %lu is not a file or directory",
|
||||
pr_err("inode %lu is not a file or directory",
|
||||
next->d_inode->i_ino);
|
||||
ret = -ENOBUFS;
|
||||
goto error;
|
||||
@ -773,7 +768,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
|
||||
ASSERT(subdir->d_inode);
|
||||
|
||||
if (!S_ISDIR(subdir->d_inode->i_mode)) {
|
||||
kerror("%s is not a directory", dirname);
|
||||
pr_err("%s is not a directory", dirname);
|
||||
ret = -EIO;
|
||||
goto check_error;
|
||||
}
|
||||
@ -800,13 +795,13 @@ check_error:
|
||||
mkdir_error:
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
dput(subdir);
|
||||
kerror("mkdir %s failed with error %d", dirname, ret);
|
||||
pr_err("mkdir %s failed with error %d", dirname, ret);
|
||||
return ERR_PTR(ret);
|
||||
|
||||
lookup_error:
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
ret = PTR_ERR(subdir);
|
||||
kerror("Lookup %s failed with error %d", dirname, ret);
|
||||
pr_err("Lookup %s failed with error %d", dirname, ret);
|
||||
return ERR_PTR(ret);
|
||||
|
||||
nomem_d_alloc:
|
||||
@ -896,7 +891,7 @@ lookup_error:
|
||||
if (ret == -EIO) {
|
||||
cachefiles_io_error(cache, "Lookup failed");
|
||||
} else if (ret != -ENOMEM) {
|
||||
kerror("Internal error: %d", ret);
|
||||
pr_err("Internal error: %d", ret);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
@ -955,7 +950,7 @@ error:
|
||||
}
|
||||
|
||||
if (ret != -ENOMEM) {
|
||||
kerror("Internal error: %d", ret);
|
||||
pr_err("Internal error: %d", ret);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,7 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache)
|
||||
ret = set_security_override_from_ctx(new, cache->secctx);
|
||||
if (ret < 0) {
|
||||
put_cred(new);
|
||||
printk(KERN_ERR "CacheFiles:"
|
||||
" Security denies permission to nominate"
|
||||
" security context: error %d\n",
|
||||
pr_err("Security denies permission to nominate security context: error %d\n",
|
||||
ret);
|
||||
goto error;
|
||||
}
|
||||
@ -59,16 +57,14 @@ static int cachefiles_check_cache_dir(struct cachefiles_cache *cache,
|
||||
|
||||
ret = security_inode_mkdir(root->d_inode, root, 0);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "CacheFiles:"
|
||||
" Security denies permission to make dirs: error %d",
|
||||
pr_err("Security denies permission to make dirs: error %d",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = security_inode_create(root->d_inode, root, 0);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "CacheFiles:"
|
||||
" Security denies permission to create files: error %d",
|
||||
pr_err("Security denies permission to create files: error %d",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
|
@ -51,7 +51,7 @@ int cachefiles_check_object_type(struct cachefiles_object *object)
|
||||
}
|
||||
|
||||
if (ret != -EEXIST) {
|
||||
kerror("Can't set xattr on %*.*s [%lu] (err %d)",
|
||||
pr_err("Can't set xattr on %*.*s [%lu] (err %d)",
|
||||
dentry->d_name.len, dentry->d_name.len,
|
||||
dentry->d_name.name, dentry->d_inode->i_ino,
|
||||
-ret);
|
||||
@ -64,7 +64,7 @@ int cachefiles_check_object_type(struct cachefiles_object *object)
|
||||
if (ret == -ERANGE)
|
||||
goto bad_type_length;
|
||||
|
||||
kerror("Can't read xattr on %*.*s [%lu] (err %d)",
|
||||
pr_err("Can't read xattr on %*.*s [%lu] (err %d)",
|
||||
dentry->d_name.len, dentry->d_name.len,
|
||||
dentry->d_name.name, dentry->d_inode->i_ino,
|
||||
-ret);
|
||||
@ -85,14 +85,14 @@ error:
|
||||
return ret;
|
||||
|
||||
bad_type_length:
|
||||
kerror("Cache object %lu type xattr length incorrect",
|
||||
pr_err("Cache object %lu type xattr length incorrect",
|
||||
dentry->d_inode->i_ino);
|
||||
ret = -EIO;
|
||||
goto error;
|
||||
|
||||
bad_type:
|
||||
xtype[2] = 0;
|
||||
kerror("Cache object %*.*s [%lu] type %s not %s",
|
||||
pr_err("Cache object %*.*s [%lu] type %s not %s",
|
||||
dentry->d_name.len, dentry->d_name.len,
|
||||
dentry->d_name.name, dentry->d_inode->i_ino,
|
||||
xtype, type);
|
||||
@ -293,7 +293,7 @@ error:
|
||||
return ret;
|
||||
|
||||
bad_type_length:
|
||||
kerror("Cache object %lu xattr length incorrect",
|
||||
pr_err("Cache object %lu xattr length incorrect",
|
||||
dentry->d_inode->i_ino);
|
||||
ret = -EIO;
|
||||
goto error;
|
||||
|
@ -694,7 +694,7 @@ static int ceph_writepages_start(struct address_space *mapping,
|
||||
(wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD"));
|
||||
|
||||
if (fsc->mount_state == CEPH_MOUNT_SHUTDOWN) {
|
||||
pr_warning("writepage_start %p on forced umount\n", inode);
|
||||
pr_warn("writepage_start %p on forced umount\n", inode);
|
||||
return -EIO; /* we're in a forced umount, don't write! */
|
||||
}
|
||||
if (fsc->mount_options->wsize && fsc->mount_options->wsize < wsize)
|
||||
|
@ -71,9 +71,9 @@ static int mdsc_show(struct seq_file *s, void *p)
|
||||
seq_printf(s, "%s", ceph_mds_op_name(req->r_op));
|
||||
|
||||
if (req->r_got_unsafe)
|
||||
seq_printf(s, "\t(unsafe)");
|
||||
seq_puts(s, "\t(unsafe)");
|
||||
else
|
||||
seq_printf(s, "\t");
|
||||
seq_puts(s, "\t");
|
||||
|
||||
if (req->r_inode) {
|
||||
seq_printf(s, " #%llx", ceph_ino(req->r_inode));
|
||||
@ -119,7 +119,7 @@ static int mdsc_show(struct seq_file *s, void *p)
|
||||
seq_printf(s, " %s", req->r_path2);
|
||||
}
|
||||
|
||||
seq_printf(s, "\n");
|
||||
seq_puts(s, "\n");
|
||||
}
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
|
||||
|
@ -821,7 +821,7 @@ no_change:
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
}
|
||||
} else if (cap_fmode >= 0) {
|
||||
pr_warning("mds issued no caps on %llx.%llx\n",
|
||||
pr_warn("mds issued no caps on %llx.%llx\n",
|
||||
ceph_vinop(inode));
|
||||
__ceph_get_fmode(ci, cap_fmode);
|
||||
}
|
||||
|
@ -2218,13 +2218,13 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
|
||||
/* dup? */
|
||||
if ((req->r_got_unsafe && !head->safe) ||
|
||||
(req->r_got_safe && head->safe)) {
|
||||
pr_warning("got a dup %s reply on %llu from mds%d\n",
|
||||
pr_warn("got a dup %s reply on %llu from mds%d\n",
|
||||
head->safe ? "safe" : "unsafe", tid, mds);
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
goto out;
|
||||
}
|
||||
if (req->r_got_safe && !head->safe) {
|
||||
pr_warning("got unsafe after safe on %llu from mds%d\n",
|
||||
pr_warn("got unsafe after safe on %llu from mds%d\n",
|
||||
tid, mds);
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
goto out;
|
||||
@ -3525,7 +3525,7 @@ static void peer_reset(struct ceph_connection *con)
|
||||
struct ceph_mds_session *s = con->private;
|
||||
struct ceph_mds_client *mdsc = s->s_mdsc;
|
||||
|
||||
pr_warning("mds%d closed our session\n", s->s_mds);
|
||||
pr_warn("mds%d closed our session\n", s->s_mds);
|
||||
send_mds_reconnect(mdsc, s);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
|
||||
|
||||
ceph_decode_16_safe(p, end, version, bad);
|
||||
if (version > 3) {
|
||||
pr_warning("got mdsmap version %d > 3, failing", version);
|
||||
pr_warn("got mdsmap version %d > 3, failing", version);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb)
|
||||
|
||||
inode = coda_iget(sb, fid, &attr);
|
||||
if (IS_ERR(inode))
|
||||
printk("coda_cnode_make: coda_iget failed\n");
|
||||
pr_warn("%s: coda_iget failed\n", __func__);
|
||||
return inode;
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)
|
||||
unsigned long hash = coda_f2i(fid);
|
||||
|
||||
if ( !sb ) {
|
||||
printk("coda_fid_to_inode: no sb!\n");
|
||||
pr_warn("%s: no sb!\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,12 @@
|
||||
#ifndef _LINUX_CODA_FS
|
||||
#define _LINUX_CODA_FS
|
||||
|
||||
#ifdef pr_fmt
|
||||
#undef pr_fmt
|
||||
#endif
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/mm.h>
|
||||
@ -63,7 +69,7 @@ void coda_sysctl_clean(void);
|
||||
else \
|
||||
ptr = (cast)vzalloc((unsigned long) size); \
|
||||
if (!ptr) \
|
||||
printk("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
|
||||
pr_warn("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
@ -102,7 +102,7 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsig
|
||||
int type = 0;
|
||||
|
||||
if (length > CODA_MAXNAMLEN) {
|
||||
printk(KERN_ERR "name too long: lookup, %s (%*s)\n",
|
||||
pr_err("name too long: lookup, %s (%*s)\n",
|
||||
coda_i2s(dir), (int)length, name);
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
}
|
||||
@ -453,23 +453,23 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)
|
||||
ret = kernel_read(host_file, ctx->pos - 2, (char *)vdir,
|
||||
sizeof(*vdir));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "coda readdir: read dir %s failed %d\n",
|
||||
coda_f2s(&cii->c_fid), ret);
|
||||
pr_err("%s: read dir %s failed %d\n",
|
||||
__func__, coda_f2s(&cii->c_fid), ret);
|
||||
break;
|
||||
}
|
||||
if (ret == 0) break; /* end of directory file reached */
|
||||
|
||||
/* catch truncated reads */
|
||||
if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
|
||||
printk(KERN_ERR "coda readdir: short read on %s\n",
|
||||
coda_f2s(&cii->c_fid));
|
||||
pr_err("%s: short read on %s\n",
|
||||
__func__, coda_f2s(&cii->c_fid));
|
||||
ret = -EBADF;
|
||||
break;
|
||||
}
|
||||
/* validate whether the directory file actually makes sense */
|
||||
if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
|
||||
printk(KERN_ERR "coda readdir: invalid dir %s\n",
|
||||
coda_f2s(&cii->c_fid));
|
||||
pr_err("%s: invalid dir %s\n",
|
||||
__func__, coda_f2s(&cii->c_fid));
|
||||
ret = -EBADF;
|
||||
break;
|
||||
}
|
||||
@ -589,8 +589,8 @@ int coda_revalidate_inode(struct inode *inode)
|
||||
coda_vattr_to_iattr(inode, &attr);
|
||||
|
||||
if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
|
||||
printk("Coda: inode %ld, fid %s changed type!\n",
|
||||
inode->i_ino, coda_f2s(&(cii->c_fid)));
|
||||
pr_warn("inode %ld, fid %s changed type!\n",
|
||||
inode->i_ino, coda_f2s(&(cii->c_fid)));
|
||||
}
|
||||
|
||||
/* the following can happen when a local fid is replaced
|
||||
|
@ -119,12 +119,12 @@ static int get_device_index(struct coda_mount_data *data)
|
||||
int idx;
|
||||
|
||||
if (data == NULL) {
|
||||
printk("coda_read_super: Bad mount data\n");
|
||||
pr_warn("%s: Bad mount data\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data->version != CODA_MOUNT_VERSION) {
|
||||
printk("coda_read_super: Bad mount version\n");
|
||||
pr_warn("%s: Bad mount version\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -141,13 +141,13 @@ static int get_device_index(struct coda_mount_data *data)
|
||||
fdput(f);
|
||||
|
||||
if (idx < 0 || idx >= MAX_CODADEVS) {
|
||||
printk("coda_read_super: Bad minor number\n");
|
||||
pr_warn("%s: Bad minor number\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return idx;
|
||||
Ebadf:
|
||||
printk("coda_read_super: Bad file\n");
|
||||
pr_warn("%s: Bad file\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -168,19 +168,19 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
|
||||
if(idx == -1)
|
||||
idx = 0;
|
||||
|
||||
printk(KERN_INFO "coda_read_super: device index: %i\n", idx);
|
||||
pr_info("%s: device index: %i\n", __func__, idx);
|
||||
|
||||
vc = &coda_comms[idx];
|
||||
mutex_lock(&vc->vc_mutex);
|
||||
|
||||
if (!vc->vc_inuse) {
|
||||
printk("coda_read_super: No pseudo device\n");
|
||||
pr_warn("%s: No pseudo device\n", __func__);
|
||||
error = -EINVAL;
|
||||
goto unlock_out;
|
||||
}
|
||||
|
||||
if (vc->vc_sb) {
|
||||
printk("coda_read_super: Device already mounted\n");
|
||||
pr_warn("%s: Device already mounted\n", __func__);
|
||||
error = -EBUSY;
|
||||
goto unlock_out;
|
||||
}
|
||||
@ -204,22 +204,23 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
|
||||
/* get root fid from Venus: this needs the root inode */
|
||||
error = venus_rootfid(sb, &fid);
|
||||
if ( error ) {
|
||||
printk("coda_read_super: coda_get_rootfid failed with %d\n",
|
||||
error);
|
||||
pr_warn("%s: coda_get_rootfid failed with %d\n",
|
||||
__func__, error);
|
||||
goto error;
|
||||
}
|
||||
printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid));
|
||||
pr_info("%s: rootfid is %s\n", __func__, coda_f2s(&fid));
|
||||
|
||||
/* make root inode */
|
||||
root = coda_cnode_make(&fid, sb);
|
||||
if (IS_ERR(root)) {
|
||||
error = PTR_ERR(root);
|
||||
printk("Failure of coda_cnode_make for root: error %d\n", error);
|
||||
pr_warn("Failure of coda_cnode_make for root: error %d\n",
|
||||
error);
|
||||
goto error;
|
||||
}
|
||||
|
||||
printk("coda_read_super: rootinode is %ld dev %s\n",
|
||||
root->i_ino, root->i_sb->s_id);
|
||||
pr_info("%s: rootinode is %ld dev %s\n",
|
||||
__func__, root->i_ino, root->i_sb->s_id);
|
||||
sb->s_root = d_make_root(root);
|
||||
if (!sb->s_root) {
|
||||
error = -EINVAL;
|
||||
@ -246,7 +247,7 @@ static void coda_put_super(struct super_block *sb)
|
||||
sb->s_fs_info = NULL;
|
||||
mutex_unlock(&vcp->vc_mutex);
|
||||
|
||||
printk("Coda: Bye bye.\n");
|
||||
pr_info("Bye bye.\n");
|
||||
}
|
||||
|
||||
static void coda_evict_inode(struct inode *inode)
|
||||
|
@ -114,14 +114,14 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
|
||||
int size = sizeof(*dcbuf);
|
||||
|
||||
if ( nbytes < sizeof(struct coda_out_hdr) ) {
|
||||
printk("coda_downcall opc %d uniq %d, not enough!\n",
|
||||
hdr.opcode, hdr.unique);
|
||||
pr_warn("coda_downcall opc %d uniq %d, not enough!\n",
|
||||
hdr.opcode, hdr.unique);
|
||||
count = nbytes;
|
||||
goto out;
|
||||
}
|
||||
if ( nbytes > size ) {
|
||||
printk("Coda: downcall opc %d, uniq %d, too much!",
|
||||
hdr.opcode, hdr.unique);
|
||||
pr_warn("downcall opc %d, uniq %d, too much!",
|
||||
hdr.opcode, hdr.unique);
|
||||
nbytes = size;
|
||||
}
|
||||
CODA_ALLOC(dcbuf, union outputArgs *, nbytes);
|
||||
@ -136,7 +136,8 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
|
||||
|
||||
CODA_FREE(dcbuf, nbytes);
|
||||
if (error) {
|
||||
printk("psdev_write: coda_downcall error: %d\n", error);
|
||||
pr_warn("%s: coda_downcall error: %d\n",
|
||||
__func__, error);
|
||||
retval = error;
|
||||
goto out;
|
||||
}
|
||||
@ -157,16 +158,17 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
|
||||
mutex_unlock(&vcp->vc_mutex);
|
||||
|
||||
if (!req) {
|
||||
printk("psdev_write: msg (%d, %d) not found\n",
|
||||
hdr.opcode, hdr.unique);
|
||||
pr_warn("%s: msg (%d, %d) not found\n",
|
||||
__func__, hdr.opcode, hdr.unique);
|
||||
retval = -ESRCH;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* move data into response buffer. */
|
||||
if (req->uc_outSize < nbytes) {
|
||||
printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %d, uniq: %d.\n",
|
||||
req->uc_outSize, (long)nbytes, hdr.opcode, hdr.unique);
|
||||
pr_warn("%s: too much cnt: %d, cnt: %ld, opc: %d, uniq: %d.\n",
|
||||
__func__, req->uc_outSize, (long)nbytes,
|
||||
hdr.opcode, hdr.unique);
|
||||
nbytes = req->uc_outSize; /* don't have more space! */
|
||||
}
|
||||
if (copy_from_user(req->uc_data, buf, nbytes)) {
|
||||
@ -240,8 +242,8 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,
|
||||
/* Move the input args into userspace */
|
||||
count = req->uc_inSize;
|
||||
if (nbytes < req->uc_inSize) {
|
||||
printk ("psdev_read: Venus read %ld bytes of %d in message\n",
|
||||
(long)nbytes, req->uc_inSize);
|
||||
pr_warn("%s: Venus read %ld bytes of %d in message\n",
|
||||
__func__, (long)nbytes, req->uc_inSize);
|
||||
count = nbytes;
|
||||
}
|
||||
|
||||
@ -305,7 +307,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
|
||||
struct upc_req *req, *tmp;
|
||||
|
||||
if (!vcp || !vcp->vc_inuse ) {
|
||||
printk("psdev_release: Not open.\n");
|
||||
pr_warn("%s: Not open.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -354,8 +356,8 @@ static int init_coda_psdev(void)
|
||||
{
|
||||
int i, err = 0;
|
||||
if (register_chrdev(CODA_PSDEV_MAJOR, "coda", &coda_psdev_fops)) {
|
||||
printk(KERN_ERR "coda_psdev: unable to get major %d\n",
|
||||
CODA_PSDEV_MAJOR);
|
||||
pr_err("%s: unable to get major %d\n",
|
||||
__func__, CODA_PSDEV_MAJOR);
|
||||
return -EIO;
|
||||
}
|
||||
coda_psdev_class = class_create(THIS_MODULE, "coda");
|
||||
@ -393,13 +395,13 @@ static int __init init_coda(void)
|
||||
goto out2;
|
||||
status = init_coda_psdev();
|
||||
if ( status ) {
|
||||
printk("Problem (%d) in init_coda_psdev\n", status);
|
||||
pr_warn("Problem (%d) in init_coda_psdev\n", status);
|
||||
goto out1;
|
||||
}
|
||||
|
||||
status = register_filesystem(&coda_fs_type);
|
||||
if (status) {
|
||||
printk("coda: failed to register filesystem!\n");
|
||||
pr_warn("failed to register filesystem!\n");
|
||||
goto out;
|
||||
}
|
||||
return 0;
|
||||
@ -420,9 +422,8 @@ static void __exit exit_coda(void)
|
||||
int err, i;
|
||||
|
||||
err = unregister_filesystem(&coda_fs_type);
|
||||
if ( err != 0 ) {
|
||||
printk("coda: failed to unregister filesystem\n");
|
||||
}
|
||||
if (err != 0)
|
||||
pr_warn("failed to unregister filesystem\n");
|
||||
for (i = 0; i < MAX_CODADEVS; i++)
|
||||
device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
|
||||
class_destroy(coda_psdev_class);
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static struct ctl_table_header *fs_table_header;
|
||||
|
||||
static ctl_table coda_table[] = {
|
||||
static struct ctl_table coda_table[] = {
|
||||
{
|
||||
.procname = "timeout",
|
||||
.data = &coda_timeout,
|
||||
@ -39,7 +39,7 @@ static ctl_table coda_table[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static ctl_table fs_table[] = {
|
||||
static struct ctl_table fs_table[] = {
|
||||
{
|
||||
.procname = "coda",
|
||||
.mode = 0555,
|
||||
|
@ -508,8 +508,8 @@ int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
|
||||
inp->coda_ioctl.data = (char *)(INSIZE(ioctl));
|
||||
|
||||
/* get the data out of user space */
|
||||
if ( copy_from_user((char*)inp + (long)inp->coda_ioctl.data,
|
||||
data->vi.in, data->vi.in_size) ) {
|
||||
if (copy_from_user((char *)inp + (long)inp->coda_ioctl.data,
|
||||
data->vi.in, data->vi.in_size)) {
|
||||
error = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
@ -518,8 +518,8 @@ int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
|
||||
&outsize, inp);
|
||||
|
||||
if (error) {
|
||||
printk("coda_pioctl: Venus returns: %d for %s\n",
|
||||
error, coda_f2s(fid));
|
||||
pr_warn("%s: Venus returns: %d for %s\n",
|
||||
__func__, error, coda_f2s(fid));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -675,7 +675,7 @@ static int coda_upcall(struct venus_comm *vcp,
|
||||
mutex_lock(&vcp->vc_mutex);
|
||||
|
||||
if (!vcp->vc_inuse) {
|
||||
printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
|
||||
pr_notice("Venus dead, not sending upcall\n");
|
||||
error = -ENXIO;
|
||||
goto exit;
|
||||
}
|
||||
@ -725,7 +725,7 @@ static int coda_upcall(struct venus_comm *vcp,
|
||||
|
||||
error = -EINTR;
|
||||
if ((req->uc_flags & CODA_REQ_ABORT) || !signal_pending(current)) {
|
||||
printk(KERN_WARNING "coda: Unexpected interruption.\n");
|
||||
pr_warn("Unexpected interruption.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -735,7 +735,7 @@ static int coda_upcall(struct venus_comm *vcp,
|
||||
|
||||
/* Venus saw the upcall, make sure we can send interrupt signal */
|
||||
if (!vcp->vc_inuse) {
|
||||
printk(KERN_INFO "coda: Venus dead, not sending signal.\n");
|
||||
pr_info("Venus dead, not sending signal.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ static long get_nr_dentry_unused(void)
|
||||
return sum < 0 ? 0 : sum;
|
||||
}
|
||||
|
||||
int proc_nr_dentry(ctl_table *table, int write, void __user *buffer,
|
||||
int proc_nr_dentry(struct ctl_table *table, int write, void __user *buffer,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
dentry_stat.nr_dentry = get_nr_dentry();
|
||||
|
@ -10,6 +10,8 @@
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
@ -148,10 +150,10 @@ static inline struct super_block *pts_sb_from_inode(struct inode *inode)
|
||||
|
||||
/*
|
||||
* parse_mount_options():
|
||||
* Set @opts to mount options specified in @data. If an option is not
|
||||
* specified in @data, set it to its default value. The exception is
|
||||
* 'newinstance' option which can only be set/cleared on a mount (i.e.
|
||||
* cannot be changed during remount).
|
||||
* Set @opts to mount options specified in @data. If an option is not
|
||||
* specified in @data, set it to its default value. The exception is
|
||||
* 'newinstance' option which can only be set/cleared on a mount (i.e.
|
||||
* cannot be changed during remount).
|
||||
*
|
||||
* Note: @data may be NULL (in which case all options are set to default).
|
||||
*/
|
||||
@ -225,7 +227,7 @@ static int parse_mount_options(char *data, int op, struct pts_mount_opts *opts)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printk(KERN_ERR "devpts: called with bogus options\n");
|
||||
pr_err("called with bogus options\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -261,7 +263,7 @@ static int mknod_ptmx(struct super_block *sb)
|
||||
|
||||
dentry = d_alloc_name(root, "ptmx");
|
||||
if (!dentry) {
|
||||
printk(KERN_NOTICE "Unable to alloc dentry for ptmx node\n");
|
||||
pr_err("Unable to alloc dentry for ptmx node\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -270,7 +272,7 @@ static int mknod_ptmx(struct super_block *sb)
|
||||
*/
|
||||
inode = new_inode(sb);
|
||||
if (!inode) {
|
||||
printk(KERN_ERR "Unable to alloc inode for ptmx node\n");
|
||||
pr_err("Unable to alloc inode for ptmx node\n");
|
||||
dput(dentry);
|
||||
goto out;
|
||||
}
|
||||
@ -303,7 +305,7 @@ static void update_ptmx_mode(struct pts_fs_info *fsi)
|
||||
#else
|
||||
static inline void update_ptmx_mode(struct pts_fs_info *fsi)
|
||||
{
|
||||
return;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -333,9 +335,11 @@ static int devpts_show_options(struct seq_file *seq, struct dentry *root)
|
||||
struct pts_mount_opts *opts = &fsi->mount_opts;
|
||||
|
||||
if (opts->setuid)
|
||||
seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, opts->uid));
|
||||
seq_printf(seq, ",uid=%u",
|
||||
from_kuid_munged(&init_user_ns, opts->uid));
|
||||
if (opts->setgid)
|
||||
seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, opts->gid));
|
||||
seq_printf(seq, ",gid=%u",
|
||||
from_kgid_munged(&init_user_ns, opts->gid));
|
||||
seq_printf(seq, ",mode=%03o", opts->mode);
|
||||
#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
|
||||
seq_printf(seq, ",ptmxmode=%03o", opts->ptmxmode);
|
||||
@ -396,7 +400,7 @@ devpts_fill_super(struct super_block *s, void *data, int silent)
|
||||
if (s->s_root)
|
||||
return 0;
|
||||
|
||||
printk(KERN_ERR "devpts: get root dentry failed\n");
|
||||
pr_err("get root dentry failed\n");
|
||||
|
||||
fail:
|
||||
return -ENOMEM;
|
||||
|
@ -157,11 +157,13 @@ static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
unsigned int x;
|
||||
int rc;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
x = simple_strtoul(buf, NULL, 0);
|
||||
rc = kstrtouint(buf, 0, &x);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (check_zero && !x)
|
||||
return -EINVAL;
|
||||
@ -730,7 +732,10 @@ static ssize_t comm_nodeid_read(struct dlm_comm *cm, char *buf)
|
||||
static ssize_t comm_nodeid_write(struct dlm_comm *cm, const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
cm->nodeid = simple_strtol(buf, NULL, 0);
|
||||
int rc = kstrtoint(buf, 0, &cm->nodeid);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -742,7 +747,10 @@ static ssize_t comm_local_read(struct dlm_comm *cm, char *buf)
|
||||
static ssize_t comm_local_write(struct dlm_comm *cm, const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
cm->local= simple_strtol(buf, NULL, 0);
|
||||
int rc = kstrtoint(buf, 0, &cm->local);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
if (cm->local && !local_comm)
|
||||
local_comm = cm;
|
||||
return len;
|
||||
@ -846,7 +854,10 @@ static ssize_t node_nodeid_write(struct dlm_node *nd, const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
uint32_t seq = 0;
|
||||
nd->nodeid = simple_strtol(buf, NULL, 0);
|
||||
int rc = kstrtoint(buf, 0, &nd->nodeid);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
dlm_comm_seq(nd->nodeid, &seq);
|
||||
nd->comm_seq = seq;
|
||||
return len;
|
||||
@ -860,7 +871,10 @@ static ssize_t node_weight_read(struct dlm_node *nd, char *buf)
|
||||
static ssize_t node_weight_write(struct dlm_node *nd, const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
nd->weight = simple_strtol(buf, NULL, 0);
|
||||
int rc = kstrtoint(buf, 0, &nd->weight);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ static int print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb,
|
||||
if (lkb->lkb_wait_type)
|
||||
seq_printf(s, " wait_type: %d", lkb->lkb_wait_type);
|
||||
|
||||
return seq_printf(s, "\n");
|
||||
return seq_puts(s, "\n");
|
||||
}
|
||||
|
||||
static int print_format1(struct dlm_rsb *res, struct seq_file *s)
|
||||
@ -92,31 +92,31 @@ static int print_format1(struct dlm_rsb *res, struct seq_file *s)
|
||||
}
|
||||
|
||||
if (res->res_nodeid > 0)
|
||||
rv = seq_printf(s, "\" \nLocal Copy, Master is node %d\n",
|
||||
rv = seq_printf(s, "\"\nLocal Copy, Master is node %d\n",
|
||||
res->res_nodeid);
|
||||
else if (res->res_nodeid == 0)
|
||||
rv = seq_printf(s, "\" \nMaster Copy\n");
|
||||
rv = seq_puts(s, "\"\nMaster Copy\n");
|
||||
else if (res->res_nodeid == -1)
|
||||
rv = seq_printf(s, "\" \nLooking up master (lkid %x)\n",
|
||||
rv = seq_printf(s, "\"\nLooking up master (lkid %x)\n",
|
||||
res->res_first_lkid);
|
||||
else
|
||||
rv = seq_printf(s, "\" \nInvalid master %d\n",
|
||||
rv = seq_printf(s, "\"\nInvalid master %d\n",
|
||||
res->res_nodeid);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
/* Print the LVB: */
|
||||
if (res->res_lvbptr) {
|
||||
seq_printf(s, "LVB: ");
|
||||
seq_puts(s, "LVB: ");
|
||||
for (i = 0; i < lvblen; i++) {
|
||||
if (i == lvblen / 2)
|
||||
seq_printf(s, "\n ");
|
||||
seq_puts(s, "\n ");
|
||||
seq_printf(s, "%02x ",
|
||||
(unsigned char) res->res_lvbptr[i]);
|
||||
}
|
||||
if (rsb_flag(res, RSB_VALNOTVALID))
|
||||
seq_printf(s, " (INVALID)");
|
||||
rv = seq_printf(s, "\n");
|
||||
seq_puts(s, " (INVALID)");
|
||||
rv = seq_puts(s, "\n");
|
||||
if (rv)
|
||||
goto out;
|
||||
}
|
||||
@ -133,21 +133,21 @@ static int print_format1(struct dlm_rsb *res, struct seq_file *s)
|
||||
}
|
||||
|
||||
/* Print the locks attached to this resource */
|
||||
seq_printf(s, "Granted Queue\n");
|
||||
seq_puts(s, "Granted Queue\n");
|
||||
list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue) {
|
||||
rv = print_format1_lock(s, lkb, res);
|
||||
if (rv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
seq_printf(s, "Conversion Queue\n");
|
||||
seq_puts(s, "Conversion Queue\n");
|
||||
list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue) {
|
||||
rv = print_format1_lock(s, lkb, res);
|
||||
if (rv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
seq_printf(s, "Waiting Queue\n");
|
||||
seq_puts(s, "Waiting Queue\n");
|
||||
list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue) {
|
||||
rv = print_format1_lock(s, lkb, res);
|
||||
if (rv)
|
||||
@ -157,13 +157,13 @@ static int print_format1(struct dlm_rsb *res, struct seq_file *s)
|
||||
if (list_empty(&res->res_lookup))
|
||||
goto out;
|
||||
|
||||
seq_printf(s, "Lookup Queue\n");
|
||||
seq_puts(s, "Lookup Queue\n");
|
||||
list_for_each_entry(lkb, &res->res_lookup, lkb_rsb_lookup) {
|
||||
rv = seq_printf(s, "%08x %s", lkb->lkb_id,
|
||||
print_lockmode(lkb->lkb_rqmode));
|
||||
if (lkb->lkb_wait_type)
|
||||
seq_printf(s, " wait_type: %d", lkb->lkb_wait_type);
|
||||
rv = seq_printf(s, "\n");
|
||||
rv = seq_puts(s, "\n");
|
||||
}
|
||||
out:
|
||||
unlock_rsb(res);
|
||||
@ -300,7 +300,7 @@ static int print_format3(struct dlm_rsb *r, struct seq_file *s)
|
||||
else
|
||||
seq_printf(s, " %02x", (unsigned char)r->res_name[i]);
|
||||
}
|
||||
rv = seq_printf(s, "\n");
|
||||
rv = seq_puts(s, "\n");
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
@ -311,7 +311,7 @@ static int print_format3(struct dlm_rsb *r, struct seq_file *s)
|
||||
|
||||
for (i = 0; i < lvblen; i++)
|
||||
seq_printf(s, " %02x", (unsigned char)r->res_lvbptr[i]);
|
||||
rv = seq_printf(s, "\n");
|
||||
rv = seq_puts(s, "\n");
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
@ -377,7 +377,7 @@ static int print_format4(struct dlm_rsb *r, struct seq_file *s)
|
||||
else
|
||||
seq_printf(s, " %02x", (unsigned char)r->res_name[i]);
|
||||
}
|
||||
rv = seq_printf(s, "\n");
|
||||
rv = seq_puts(s, "\n");
|
||||
out:
|
||||
unlock_rsb(r);
|
||||
return rv;
|
||||
|
@ -35,8 +35,11 @@ static struct task_struct * scand_task;
|
||||
static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len)
|
||||
{
|
||||
ssize_t ret = len;
|
||||
int n = simple_strtol(buf, NULL, 0);
|
||||
int n;
|
||||
int rc = kstrtoint(buf, 0, &n);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
ls = dlm_find_lockspace_local(ls->ls_local_handle);
|
||||
if (!ls)
|
||||
return -EINVAL;
|
||||
@ -57,7 +60,10 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len)
|
||||
|
||||
static ssize_t dlm_event_store(struct dlm_ls *ls, const char *buf, size_t len)
|
||||
{
|
||||
ls->ls_uevent_result = simple_strtol(buf, NULL, 0);
|
||||
int rc = kstrtoint(buf, 0, &ls->ls_uevent_result);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
set_bit(LSFL_UEVENT_WAIT, &ls->ls_flags);
|
||||
wake_up(&ls->ls_uevent_wait);
|
||||
return len;
|
||||
@ -70,7 +76,10 @@ static ssize_t dlm_id_show(struct dlm_ls *ls, char *buf)
|
||||
|
||||
static ssize_t dlm_id_store(struct dlm_ls *ls, const char *buf, size_t len)
|
||||
{
|
||||
ls->ls_global_id = simple_strtoul(buf, NULL, 0);
|
||||
int rc = kstrtouint(buf, 0, &ls->ls_global_id);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -81,7 +90,11 @@ static ssize_t dlm_nodir_show(struct dlm_ls *ls, char *buf)
|
||||
|
||||
static ssize_t dlm_nodir_store(struct dlm_ls *ls, const char *buf, size_t len)
|
||||
{
|
||||
int val = simple_strtoul(buf, NULL, 0);
|
||||
int val;
|
||||
int rc = kstrtoint(buf, 0, &val);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
if (val == 1)
|
||||
set_bit(LSFL_NODIR, &ls->ls_flags);
|
||||
return len;
|
||||
|
@ -50,7 +50,7 @@ static void drop_slab(void)
|
||||
} while (nr_objects > 10);
|
||||
}
|
||||
|
||||
int drop_caches_sysctl_handler(ctl_table *table, int write,
|
||||
int drop_caches_sysctl_handler(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *length, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
|
@ -293,7 +293,7 @@ static LIST_HEAD(tfile_check_list);
|
||||
static long zero;
|
||||
static long long_max = LONG_MAX;
|
||||
|
||||
ctl_table epoll_table[] = {
|
||||
struct ctl_table epoll_table[] = {
|
||||
{
|
||||
.procname = "max_user_watches",
|
||||
.data = &max_user_watches,
|
||||
|
@ -52,7 +52,8 @@ struct fat_mount_options {
|
||||
usefree:1, /* Use free_clusters for FAT32 */
|
||||
tz_set:1, /* Filesystem timestamps' offset set */
|
||||
rodir:1, /* allow ATTR_RO for directory */
|
||||
discard:1; /* Issue discard requests on deletions */
|
||||
discard:1, /* Issue discard requests on deletions */
|
||||
dos1xfloppy:1; /* Assume default BPB for DOS 1.x floppies */
|
||||
};
|
||||
|
||||
#define FAT_HASH_BITS 8
|
||||
|
345
fs/fat/inode.c
345
fs/fat/inode.c
@ -35,9 +35,71 @@
|
||||
#define CONFIG_FAT_DEFAULT_IOCHARSET ""
|
||||
#endif
|
||||
|
||||
#define KB_IN_SECTORS 2
|
||||
|
||||
/*
|
||||
* A deserialized copy of the on-disk structure laid out in struct
|
||||
* fat_boot_sector.
|
||||
*/
|
||||
struct fat_bios_param_block {
|
||||
u16 fat_sector_size;
|
||||
u8 fat_sec_per_clus;
|
||||
u16 fat_reserved;
|
||||
u8 fat_fats;
|
||||
u16 fat_dir_entries;
|
||||
u16 fat_sectors;
|
||||
u16 fat_fat_length;
|
||||
u32 fat_total_sect;
|
||||
|
||||
u8 fat16_state;
|
||||
u32 fat16_vol_id;
|
||||
|
||||
u32 fat32_length;
|
||||
u32 fat32_root_cluster;
|
||||
u16 fat32_info_sector;
|
||||
u8 fat32_state;
|
||||
u32 fat32_vol_id;
|
||||
};
|
||||
|
||||
static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
|
||||
static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
|
||||
|
||||
static struct fat_floppy_defaults {
|
||||
unsigned nr_sectors;
|
||||
unsigned sec_per_clus;
|
||||
unsigned dir_entries;
|
||||
unsigned media;
|
||||
unsigned fat_length;
|
||||
} floppy_defaults[] = {
|
||||
{
|
||||
.nr_sectors = 160 * KB_IN_SECTORS,
|
||||
.sec_per_clus = 1,
|
||||
.dir_entries = 64,
|
||||
.media = 0xFE,
|
||||
.fat_length = 1,
|
||||
},
|
||||
{
|
||||
.nr_sectors = 180 * KB_IN_SECTORS,
|
||||
.sec_per_clus = 1,
|
||||
.dir_entries = 64,
|
||||
.media = 0xFC,
|
||||
.fat_length = 2,
|
||||
},
|
||||
{
|
||||
.nr_sectors = 320 * KB_IN_SECTORS,
|
||||
.sec_per_clus = 2,
|
||||
.dir_entries = 112,
|
||||
.media = 0xFF,
|
||||
.fat_length = 1,
|
||||
},
|
||||
{
|
||||
.nr_sectors = 360 * KB_IN_SECTORS,
|
||||
.sec_per_clus = 2,
|
||||
.dir_entries = 112,
|
||||
.media = 0xFD,
|
||||
.fat_length = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static int fat_add_cluster(struct inode *inode)
|
||||
{
|
||||
@ -359,7 +421,7 @@ struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
|
||||
|
||||
static int is_exec(unsigned char *extension)
|
||||
{
|
||||
unsigned char *exe_extensions = "EXECOMBAT", *walk;
|
||||
unsigned char exe_extensions[] = "EXECOMBAT", *walk;
|
||||
|
||||
for (walk = exe_extensions; *walk; walk += 3)
|
||||
if (!strncmp(extension, walk, 3))
|
||||
@ -853,6 +915,8 @@ static int fat_show_options(struct seq_file *m, struct dentry *root)
|
||||
seq_puts(m, ",nfs=stale_rw");
|
||||
if (opts->discard)
|
||||
seq_puts(m, ",discard");
|
||||
if (opts->dos1xfloppy)
|
||||
seq_puts(m, ",dos1xfloppy");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -867,7 +931,7 @@ enum {
|
||||
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
|
||||
Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont,
|
||||
Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset,
|
||||
Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err,
|
||||
Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err, Opt_dos1xfloppy,
|
||||
};
|
||||
|
||||
static const match_table_t fat_tokens = {
|
||||
@ -900,6 +964,7 @@ static const match_table_t fat_tokens = {
|
||||
{Opt_nfs_stale_rw, "nfs"},
|
||||
{Opt_nfs_stale_rw, "nfs=stale_rw"},
|
||||
{Opt_nfs_nostale_ro, "nfs=nostale_ro"},
|
||||
{Opt_dos1xfloppy, "dos1xfloppy"},
|
||||
{Opt_obsolete, "conv=binary"},
|
||||
{Opt_obsolete, "conv=text"},
|
||||
{Opt_obsolete, "conv=auto"},
|
||||
@ -1102,6 +1167,9 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
|
||||
case Opt_nfs_nostale_ro:
|
||||
opts->nfs = FAT_NFS_NOSTALE_RO;
|
||||
break;
|
||||
case Opt_dos1xfloppy:
|
||||
opts->dos1xfloppy = 1;
|
||||
break;
|
||||
|
||||
/* msdos specific */
|
||||
case Opt_dots:
|
||||
@ -1247,6 +1315,169 @@ static unsigned long calc_fat_clusters(struct super_block *sb)
|
||||
return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
|
||||
}
|
||||
|
||||
static bool fat_bpb_is_zero(struct fat_boot_sector *b)
|
||||
{
|
||||
if (get_unaligned_le16(&b->sector_size))
|
||||
return false;
|
||||
if (b->sec_per_clus)
|
||||
return false;
|
||||
if (b->reserved)
|
||||
return false;
|
||||
if (b->fats)
|
||||
return false;
|
||||
if (get_unaligned_le16(&b->dir_entries))
|
||||
return false;
|
||||
if (get_unaligned_le16(&b->sectors))
|
||||
return false;
|
||||
if (b->media)
|
||||
return false;
|
||||
if (b->fat_length)
|
||||
return false;
|
||||
if (b->secs_track)
|
||||
return false;
|
||||
if (b->heads)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int fat_read_bpb(struct super_block *sb, struct fat_boot_sector *b,
|
||||
int silent, struct fat_bios_param_block *bpb)
|
||||
{
|
||||
int error = -EINVAL;
|
||||
|
||||
/* Read in BPB ... */
|
||||
memset(bpb, 0, sizeof(*bpb));
|
||||
bpb->fat_sector_size = get_unaligned_le16(&b->sector_size);
|
||||
bpb->fat_sec_per_clus = b->sec_per_clus;
|
||||
bpb->fat_reserved = le16_to_cpu(b->reserved);
|
||||
bpb->fat_fats = b->fats;
|
||||
bpb->fat_dir_entries = get_unaligned_le16(&b->dir_entries);
|
||||
bpb->fat_sectors = get_unaligned_le16(&b->sectors);
|
||||
bpb->fat_fat_length = le16_to_cpu(b->fat_length);
|
||||
bpb->fat_total_sect = le32_to_cpu(b->total_sect);
|
||||
|
||||
bpb->fat16_state = b->fat16.state;
|
||||
bpb->fat16_vol_id = get_unaligned_le32(b->fat16.vol_id);
|
||||
|
||||
bpb->fat32_length = le32_to_cpu(b->fat32.length);
|
||||
bpb->fat32_root_cluster = le32_to_cpu(b->fat32.root_cluster);
|
||||
bpb->fat32_info_sector = le16_to_cpu(b->fat32.info_sector);
|
||||
bpb->fat32_state = b->fat32.state;
|
||||
bpb->fat32_vol_id = get_unaligned_le32(b->fat32.vol_id);
|
||||
|
||||
/* Validate this looks like a FAT filesystem BPB */
|
||||
if (!bpb->fat_reserved) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR,
|
||||
"bogus number of reserved sectors");
|
||||
goto out;
|
||||
}
|
||||
if (!bpb->fat_fats) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "bogus number of FAT structure");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Earlier we checked here that b->secs_track and b->head are nonzero,
|
||||
* but it turns out valid FAT filesystems can have zero there.
|
||||
*/
|
||||
|
||||
if (!fat_valid_media(b->media)) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "invalid media value (0x%02x)",
|
||||
(unsigned)b->media);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!is_power_of_2(bpb->fat_sector_size)
|
||||
|| (bpb->fat_sector_size < 512)
|
||||
|| (bpb->fat_sector_size > 4096)) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "bogus logical sector size %u",
|
||||
(unsigned)bpb->fat_sector_size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!is_power_of_2(bpb->fat_sec_per_clus)) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "bogus sectors per cluster %u",
|
||||
(unsigned)bpb->fat_sec_per_clus);
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int fat_read_static_bpb(struct super_block *sb,
|
||||
struct fat_boot_sector *b, int silent,
|
||||
struct fat_bios_param_block *bpb)
|
||||
{
|
||||
static const char *notdos1x = "This doesn't look like a DOS 1.x volume";
|
||||
|
||||
struct fat_floppy_defaults *fdefaults = NULL;
|
||||
int error = -EINVAL;
|
||||
sector_t bd_sects;
|
||||
unsigned i;
|
||||
|
||||
bd_sects = i_size_read(sb->s_bdev->bd_inode) / SECTOR_SIZE;
|
||||
|
||||
/* 16-bit DOS 1.x reliably wrote bootstrap short-jmp code */
|
||||
if (b->ignored[0] != 0xeb || b->ignored[2] != 0x90) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR,
|
||||
"%s; no bootstrapping code", notdos1x);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If any value in this region is non-zero, it isn't archaic
|
||||
* DOS.
|
||||
*/
|
||||
if (!fat_bpb_is_zero(b)) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR,
|
||||
"%s; DOS 2.x BPB is non-zero", notdos1x);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(floppy_defaults); i++) {
|
||||
if (floppy_defaults[i].nr_sectors == bd_sects) {
|
||||
fdefaults = &floppy_defaults[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fdefaults == NULL) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_WARNING,
|
||||
"This looks like a DOS 1.x volume, but isn't a recognized floppy size (%llu sectors)",
|
||||
(u64)bd_sects);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_INFO,
|
||||
"This looks like a DOS 1.x volume; assuming default BPB values");
|
||||
|
||||
memset(bpb, 0, sizeof(*bpb));
|
||||
bpb->fat_sector_size = SECTOR_SIZE;
|
||||
bpb->fat_sec_per_clus = fdefaults->sec_per_clus;
|
||||
bpb->fat_reserved = 1;
|
||||
bpb->fat_fats = 2;
|
||||
bpb->fat_dir_entries = fdefaults->dir_entries;
|
||||
bpb->fat_sectors = fdefaults->nr_sectors;
|
||||
bpb->fat_fat_length = fdefaults->fat_length;
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the super block of an MS-DOS FS.
|
||||
*/
|
||||
@ -1256,12 +1487,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
|
||||
struct inode *root_inode = NULL, *fat_inode = NULL;
|
||||
struct inode *fsinfo_inode = NULL;
|
||||
struct buffer_head *bh;
|
||||
struct fat_boot_sector *b;
|
||||
struct fat_bios_param_block bpb;
|
||||
struct msdos_sb_info *sbi;
|
||||
u16 logical_sector_size;
|
||||
u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors;
|
||||
int debug;
|
||||
unsigned int media;
|
||||
long error;
|
||||
char buf[50];
|
||||
|
||||
@ -1298,100 +1528,72 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
b = (struct fat_boot_sector *) bh->b_data;
|
||||
if (!b->reserved) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "bogus number of reserved sectors");
|
||||
brelse(bh);
|
||||
goto out_invalid;
|
||||
}
|
||||
if (!b->fats) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "bogus number of FAT structure");
|
||||
brelse(bh);
|
||||
goto out_invalid;
|
||||
}
|
||||
error = fat_read_bpb(sb, (struct fat_boot_sector *)bh->b_data, silent,
|
||||
&bpb);
|
||||
if (error == -EINVAL && sbi->options.dos1xfloppy)
|
||||
error = fat_read_static_bpb(sb,
|
||||
(struct fat_boot_sector *)bh->b_data, silent, &bpb);
|
||||
brelse(bh);
|
||||
|
||||
/*
|
||||
* Earlier we checked here that b->secs_track and b->head are nonzero,
|
||||
* but it turns out valid FAT filesystems can have zero there.
|
||||
*/
|
||||
if (error == -EINVAL)
|
||||
goto out_invalid;
|
||||
else if (error)
|
||||
goto out_fail;
|
||||
|
||||
media = b->media;
|
||||
if (!fat_valid_media(media)) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "invalid media value (0x%02x)",
|
||||
media);
|
||||
brelse(bh);
|
||||
goto out_invalid;
|
||||
}
|
||||
logical_sector_size = get_unaligned_le16(&b->sector_size);
|
||||
if (!is_power_of_2(logical_sector_size)
|
||||
|| (logical_sector_size < 512)
|
||||
|| (logical_sector_size > 4096)) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "bogus logical sector size %u",
|
||||
logical_sector_size);
|
||||
brelse(bh);
|
||||
goto out_invalid;
|
||||
}
|
||||
sbi->sec_per_clus = b->sec_per_clus;
|
||||
if (!is_power_of_2(sbi->sec_per_clus)) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "bogus sectors per cluster %u",
|
||||
sbi->sec_per_clus);
|
||||
brelse(bh);
|
||||
goto out_invalid;
|
||||
}
|
||||
logical_sector_size = bpb.fat_sector_size;
|
||||
sbi->sec_per_clus = bpb.fat_sec_per_clus;
|
||||
|
||||
error = -EIO;
|
||||
if (logical_sector_size < sb->s_blocksize) {
|
||||
fat_msg(sb, KERN_ERR, "logical sector size too small for device"
|
||||
" (logical sector size = %u)", logical_sector_size);
|
||||
brelse(bh);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (logical_sector_size > sb->s_blocksize) {
|
||||
brelse(bh);
|
||||
struct buffer_head *bh_resize;
|
||||
|
||||
if (!sb_set_blocksize(sb, logical_sector_size)) {
|
||||
fat_msg(sb, KERN_ERR, "unable to set blocksize %u",
|
||||
logical_sector_size);
|
||||
goto out_fail;
|
||||
}
|
||||
bh = sb_bread(sb, 0);
|
||||
if (bh == NULL) {
|
||||
|
||||
/* Verify that the larger boot sector is fully readable */
|
||||
bh_resize = sb_bread(sb, 0);
|
||||
if (bh_resize == NULL) {
|
||||
fat_msg(sb, KERN_ERR, "unable to read boot sector"
|
||||
" (logical sector size = %lu)",
|
||||
sb->s_blocksize);
|
||||
goto out_fail;
|
||||
}
|
||||
b = (struct fat_boot_sector *) bh->b_data;
|
||||
brelse(bh_resize);
|
||||
}
|
||||
|
||||
mutex_init(&sbi->s_lock);
|
||||
sbi->cluster_size = sb->s_blocksize * sbi->sec_per_clus;
|
||||
sbi->cluster_bits = ffs(sbi->cluster_size) - 1;
|
||||
sbi->fats = b->fats;
|
||||
sbi->fats = bpb.fat_fats;
|
||||
sbi->fat_bits = 0; /* Don't know yet */
|
||||
sbi->fat_start = le16_to_cpu(b->reserved);
|
||||
sbi->fat_length = le16_to_cpu(b->fat_length);
|
||||
sbi->fat_start = bpb.fat_reserved;
|
||||
sbi->fat_length = bpb.fat_fat_length;
|
||||
sbi->root_cluster = 0;
|
||||
sbi->free_clusters = -1; /* Don't know yet */
|
||||
sbi->free_clus_valid = 0;
|
||||
sbi->prev_free = FAT_START_ENT;
|
||||
sb->s_maxbytes = 0xffffffff;
|
||||
|
||||
if (!sbi->fat_length && b->fat32.length) {
|
||||
if (!sbi->fat_length && bpb.fat32_length) {
|
||||
struct fat_boot_fsinfo *fsinfo;
|
||||
struct buffer_head *fsinfo_bh;
|
||||
|
||||
/* Must be FAT32 */
|
||||
sbi->fat_bits = 32;
|
||||
sbi->fat_length = le32_to_cpu(b->fat32.length);
|
||||
sbi->root_cluster = le32_to_cpu(b->fat32.root_cluster);
|
||||
sbi->fat_length = bpb.fat32_length;
|
||||
sbi->root_cluster = bpb.fat32_root_cluster;
|
||||
|
||||
/* MC - if info_sector is 0, don't multiply by 0 */
|
||||
sbi->fsinfo_sector = le16_to_cpu(b->fat32.info_sector);
|
||||
sbi->fsinfo_sector = bpb.fat32_info_sector;
|
||||
if (sbi->fsinfo_sector == 0)
|
||||
sbi->fsinfo_sector = 1;
|
||||
|
||||
@ -1399,7 +1601,6 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
|
||||
if (fsinfo_bh == NULL) {
|
||||
fat_msg(sb, KERN_ERR, "bread failed, FSINFO block"
|
||||
" (sector = %lu)", sbi->fsinfo_sector);
|
||||
brelse(bh);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
@ -1422,35 +1623,28 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
|
||||
|
||||
/* interpret volume ID as a little endian 32 bit integer */
|
||||
if (sbi->fat_bits == 32)
|
||||
sbi->vol_id = (((u32)b->fat32.vol_id[0]) |
|
||||
((u32)b->fat32.vol_id[1] << 8) |
|
||||
((u32)b->fat32.vol_id[2] << 16) |
|
||||
((u32)b->fat32.vol_id[3] << 24));
|
||||
sbi->vol_id = bpb.fat32_vol_id;
|
||||
else /* fat 16 or 12 */
|
||||
sbi->vol_id = (((u32)b->fat16.vol_id[0]) |
|
||||
((u32)b->fat16.vol_id[1] << 8) |
|
||||
((u32)b->fat16.vol_id[2] << 16) |
|
||||
((u32)b->fat16.vol_id[3] << 24));
|
||||
sbi->vol_id = bpb.fat16_vol_id;
|
||||
|
||||
sbi->dir_per_block = sb->s_blocksize / sizeof(struct msdos_dir_entry);
|
||||
sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1;
|
||||
|
||||
sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length;
|
||||
sbi->dir_entries = get_unaligned_le16(&b->dir_entries);
|
||||
sbi->dir_entries = bpb.fat_dir_entries;
|
||||
if (sbi->dir_entries & (sbi->dir_per_block - 1)) {
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "bogus directory-entries per block"
|
||||
" (%u)", sbi->dir_entries);
|
||||
brelse(bh);
|
||||
goto out_invalid;
|
||||
}
|
||||
|
||||
rootdir_sectors = sbi->dir_entries
|
||||
* sizeof(struct msdos_dir_entry) / sb->s_blocksize;
|
||||
sbi->data_start = sbi->dir_start + rootdir_sectors;
|
||||
total_sectors = get_unaligned_le16(&b->sectors);
|
||||
total_sectors = bpb.fat_sectors;
|
||||
if (total_sectors == 0)
|
||||
total_sectors = le32_to_cpu(b->total_sect);
|
||||
total_sectors = bpb.fat_total_sect;
|
||||
|
||||
total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
|
||||
|
||||
@ -1459,9 +1653,9 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
|
||||
|
||||
/* some OSes set FAT_STATE_DIRTY and clean it on unmount. */
|
||||
if (sbi->fat_bits == 32)
|
||||
sbi->dirty = b->fat32.state & FAT_STATE_DIRTY;
|
||||
sbi->dirty = bpb.fat32_state & FAT_STATE_DIRTY;
|
||||
else /* fat 16 or 12 */
|
||||
sbi->dirty = b->fat16.state & FAT_STATE_DIRTY;
|
||||
sbi->dirty = bpb.fat16_state & FAT_STATE_DIRTY;
|
||||
|
||||
/* check that FAT table does not overflow */
|
||||
fat_clusters = calc_fat_clusters(sb);
|
||||
@ -1470,7 +1664,6 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
|
||||
if (!silent)
|
||||
fat_msg(sb, KERN_ERR, "count of clusters too big (%u)",
|
||||
total_clusters);
|
||||
brelse(bh);
|
||||
goto out_invalid;
|
||||
}
|
||||
|
||||
@ -1483,8 +1676,6 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
|
||||
if (sbi->prev_free < FAT_START_ENT)
|
||||
sbi->prev_free = FAT_START_ENT;
|
||||
|
||||
brelse(bh);
|
||||
|
||||
/* set up enough so that it can read an inode */
|
||||
fat_hash_init(sb);
|
||||
dir_hash_init(sb);
|
||||
|
@ -76,14 +76,14 @@ EXPORT_SYMBOL_GPL(get_max_files);
|
||||
* Handle nr_files sysctl
|
||||
*/
|
||||
#if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS)
|
||||
int proc_nr_files(ctl_table *table, int write,
|
||||
int proc_nr_files(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
files_stat.nr_files = get_nr_files();
|
||||
return proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
|
||||
}
|
||||
#else
|
||||
int proc_nr_files(ctl_table *table, int write,
|
||||
int proc_nr_files(struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
return -ENOSYS;
|
||||
|
@ -67,7 +67,7 @@ static int fscache_max_active_sysctl(struct ctl_table *table, int write,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctl_table fscache_sysctls[] = {
|
||||
struct ctl_table fscache_sysctls[] = {
|
||||
{
|
||||
.procname = "object_max_active",
|
||||
.data = &fscache_object_max_active,
|
||||
@ -87,7 +87,7 @@ ctl_table fscache_sysctls[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
ctl_table fscache_sysctls_root[] = {
|
||||
struct ctl_table fscache_sysctls_root[] = {
|
||||
{
|
||||
.procname = "fscache",
|
||||
.mode = 0555,
|
||||
|
@ -54,14 +54,11 @@ int hfsplus_attr_build_key(struct super_block *sb, hfsplus_btree_key *key,
|
||||
memset(key, 0, sizeof(struct hfsplus_attr_key));
|
||||
key->attr.cnid = cpu_to_be32(cnid);
|
||||
if (name) {
|
||||
len = strlen(name);
|
||||
if (len > HFSPLUS_ATTR_MAX_STRLEN) {
|
||||
pr_err("invalid xattr name's length\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
hfsplus_asc2uni(sb,
|
||||
int res = hfsplus_asc2uni(sb,
|
||||
(struct hfsplus_unistr *)&key->attr.key_name,
|
||||
HFSPLUS_ATTR_MAX_STRLEN, name, len);
|
||||
HFSPLUS_ATTR_MAX_STRLEN, name, strlen(name));
|
||||
if (res)
|
||||
return res;
|
||||
len = be16_to_cpu(key->attr.key_name.length);
|
||||
} else {
|
||||
key->attr.key_name.length = 0;
|
||||
@ -82,31 +79,6 @@ int hfsplus_attr_build_key(struct super_block *sb, hfsplus_btree_key *key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hfsplus_attr_build_key_uni(hfsplus_btree_key *key,
|
||||
u32 cnid,
|
||||
struct hfsplus_attr_unistr *name)
|
||||
{
|
||||
int ustrlen;
|
||||
|
||||
memset(key, 0, sizeof(struct hfsplus_attr_key));
|
||||
ustrlen = be16_to_cpu(name->length);
|
||||
key->attr.cnid = cpu_to_be32(cnid);
|
||||
key->attr.key_name.length = cpu_to_be16(ustrlen);
|
||||
ustrlen *= 2;
|
||||
memcpy(key->attr.key_name.unicode, name->unicode, ustrlen);
|
||||
|
||||
/* The length of the key, as stored in key_len field, does not include
|
||||
* the size of the key_len field itself.
|
||||
* So, offsetof(hfsplus_attr_key, key_name) is a trick because
|
||||
* it takes into consideration key_len field (__be16) of
|
||||
* hfsplus_attr_key structure instead of length field (__be16) of
|
||||
* hfsplus_attr_unistr structure.
|
||||
*/
|
||||
key->key_len =
|
||||
cpu_to_be16(offsetof(struct hfsplus_attr_key, key_name) +
|
||||
ustrlen);
|
||||
}
|
||||
|
||||
hfsplus_attr_entry *hfsplus_alloc_attr_entry(void)
|
||||
{
|
||||
return kmem_cache_alloc(hfsplus_attr_tree_cachep, GFP_KERNEL);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user