misc: tizen-inform-reboot: Use ksys_open() and ksys_close() wrappers
[platform/kernel/linux-rpi.git] / drivers / misc / tizen-inform-reboot.c
1 /*
2  * Tizen reboot parameter passing notifier
3  *
4  * Written by: Junghoon Kim <jhoon20.kim@samsung.com>
5  *
6  * Copyright (C) 2017 Samsung Electronics Co., Ltd.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/notifier.h>
14 #include <linux/reboot.h>
15 #include <linux/syscalls.h>
16 #include <linux/file.h>
17 #include <linux/fcntl.h>
18 #include <linux/uaccess.h>
19
20 static int inform_reboot_notifier(struct notifier_block *nb,
21                                                 unsigned long val, void *buf)
22 {
23         char *cmd = buf;
24         char *filename = CONFIG_TIZEN_INFORM_PATH;
25         struct file *file;
26         int fd;
27         loff_t pos = 0;
28         mm_segment_t old_fs = get_fs();
29
30         set_fs(KERNEL_DS);
31
32         fd = ksys_open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
33         if (fd >= 0) {
34                 file = fget(fd);
35                 if (file) {
36                         struct super_block *sb = file->f_path.dentry->d_sb;
37
38                         if (cmd) {
39                                 if (!strncmp(cmd, "fota", 4))
40                                         cmd = "upgr";
41                                 else if (!strncmp(cmd, "recovery", 8))
42                                         cmd = "rcvr";
43                                 else if (!strncmp(cmd, "download", 8))
44                                         cmd = "dwnl";
45                                 else
46                                         cmd = "ndef";
47                         } else
48                                 cmd = "norm";
49
50                         vfs_write(file, cmd, strlen(cmd), &pos);
51
52                         down_read(&sb->s_umount);
53                         sync_filesystem(sb);
54                         up_read(&sb->s_umount);
55
56                         fput(file);
57                 }
58                 ksys_close(fd);
59         } else {
60                 pr_err("Reboot parameter passing is failed.\n"
61                                 "Inform file path should be described correctly in config.\n");
62         }
63
64         set_fs(old_fs);
65
66         return NOTIFY_DONE;
67 }
68
69 static struct notifier_block nb_inform_reboot_block = {
70         .notifier_call = inform_reboot_notifier,
71         .priority = 256,
72 };
73
74 static int __init inform_reboot_init(void)
75 {
76         /* to support reboot parameter passing */
77         register_reboot_notifier(&nb_inform_reboot_block);
78         return 0;
79 }
80
81 subsys_initcall(inform_reboot_init);