diff options
author | Iliyan Malchev <malchev@google.com> | 2009-11-15 21:16:43 -0500 |
---|---|---|
committer | Daniel Walker <dwalker@codeaurora.org> | 2010-05-12 12:15:24 -0400 |
commit | 1207babdcdfe5501d1528c86b445a9d1045ecc01 (patch) | |
tree | e1fab45d892ab8998575066e1e9355274d0f8e43 /arch/arm/mach-msm | |
parent | 34f719b0c25cca6e11164f926fc798c25499aa96 (diff) |
[ARM] msm: add /proc/last_radio_log when supported by the modem.
Signed-off-by: Iliyan Malchev <malchev@google.com>
Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
Diffstat (limited to 'arch/arm/mach-msm')
-rw-r--r-- | arch/arm/mach-msm/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-msm/last_radio_log.c | 82 | ||||
-rw-r--r-- | arch/arm/mach-msm/smd.c | 4 |
3 files changed, 87 insertions, 0 deletions
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 9c3c4019da8a..147339c87277 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile | |||
@@ -6,6 +6,7 @@ obj-y += acpuclock-arm11.o | |||
6 | obj-y += clock.o clock-7x01a.o | 6 | obj-y += clock.o clock-7x01a.o |
7 | 7 | ||
8 | obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o | 8 | obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o |
9 | obj-$(CONFIG_MSM_SMD) += last_radio_log.o | ||
9 | 10 | ||
10 | obj-$(CONFIG_MACH_TROUT) += board-trout.o | 11 | obj-$(CONFIG_MACH_TROUT) += board-trout.o |
11 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o | 12 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o |
diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c new file mode 100644 index 000000000000..b64ba5a98686 --- /dev/null +++ b/arch/arm/mach-msm/last_radio_log.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* arch/arm/mach-msm/last_radio_log.c | ||
2 | * | ||
3 | * Extract the log from a modem crash though SMEM | ||
4 | * | ||
5 | * Copyright (C) 2007 Google, Inc. | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/fs.h> | ||
21 | #include <linux/proc_fs.h> | ||
22 | #include <linux/uaccess.h> | ||
23 | |||
24 | #include "smd_private.h" | ||
25 | |||
26 | static void *radio_log_base; | ||
27 | static size_t radio_log_size; | ||
28 | |||
29 | extern void *smem_item(unsigned id, unsigned *size); | ||
30 | |||
31 | static ssize_t last_radio_log_read(struct file *file, char __user *buf, | ||
32 | size_t len, loff_t *offset) | ||
33 | { | ||
34 | loff_t pos = *offset; | ||
35 | ssize_t count; | ||
36 | |||
37 | if (pos >= radio_log_size) | ||
38 | return 0; | ||
39 | |||
40 | count = min(len, (size_t)(radio_log_size - pos)); | ||
41 | if (copy_to_user(buf, radio_log_base + pos, count)) { | ||
42 | pr_err("%s: copy to user failed\n", __func__); | ||
43 | return -EFAULT; | ||
44 | } | ||
45 | |||
46 | *offset += count; | ||
47 | return count; | ||
48 | } | ||
49 | |||
50 | static struct file_operations last_radio_log_fops = { | ||
51 | .read = last_radio_log_read | ||
52 | }; | ||
53 | |||
54 | void msm_init_last_radio_log(struct module *owner) | ||
55 | { | ||
56 | struct proc_dir_entry *entry; | ||
57 | |||
58 | if (last_radio_log_fops.owner) { | ||
59 | pr_err("%s: already claimed\n", __func__); | ||
60 | return; | ||
61 | } | ||
62 | |||
63 | radio_log_base = smem_item(SMEM_CLKREGIM_BSP, &radio_log_size); | ||
64 | if (!radio_log_base) { | ||
65 | pr_err("%s: could not retrieve SMEM_CLKREGIM_BSP\n", __func__); | ||
66 | return; | ||
67 | } | ||
68 | |||
69 | entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL); | ||
70 | if (!entry) { | ||
71 | pr_err("%s: could not create proc entry for radio log\n", | ||
72 | __func__); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | pr_err("%s: last radio log is %d bytes long\n", __func__, | ||
77 | radio_log_size); | ||
78 | last_radio_log_fops.owner = owner; | ||
79 | entry->proc_fops = &last_radio_log_fops; | ||
80 | entry->size = radio_log_size; | ||
81 | } | ||
82 | EXPORT_SYMBOL(msm_init_last_radio_log); | ||
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index 34bcc327aa88..655fe42506ca 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c | |||
@@ -1038,6 +1038,8 @@ int smd_core_init(void) | |||
1038 | return 0; | 1038 | return 0; |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | extern void msm_init_last_radio_log(struct module *); | ||
1042 | |||
1041 | static int __init msm_smd_probe(struct platform_device *pdev) | 1043 | static int __init msm_smd_probe(struct platform_device *pdev) |
1042 | { | 1044 | { |
1043 | pr_info("smd_init()\n"); | 1045 | pr_info("smd_init()\n"); |
@@ -1053,6 +1055,8 @@ static int __init msm_smd_probe(struct platform_device *pdev) | |||
1053 | 1055 | ||
1054 | msm_check_for_modem_crash = check_for_modem_crash; | 1056 | msm_check_for_modem_crash = check_for_modem_crash; |
1055 | 1057 | ||
1058 | msm_init_last_radio_log(THIS_MODULE); | ||
1059 | |||
1056 | smd_initialized = 1; | 1060 | smd_initialized = 1; |
1057 | 1061 | ||
1058 | return 0; | 1062 | return 0; |