aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-msm/smd.c
diff options
context:
space:
mode:
authorBrian Swetland <swetland@google.com>2009-07-01 20:58:37 -0400
committerDaniel Walker <dwalker@codeaurora.org>2010-05-12 12:15:09 -0400
commit03e00cd350c6636b5f2a9854609fea93a5c7b677 (patch)
tree82c9fa41f1b21c1450500cb92577b17ed4ae8b45 /arch/arm/mach-msm/smd.c
parentec9d3d14ffa9454e6d51e5dd1889d6e9e0be5198 (diff)
[ARM] msm: cleanup smd, separate debugfs support
- pull debug code into smd_debug.c - move necessary structures and defines into smd_private.h - fix some comment formatting, etc Signed-off-by: Brian Swetland <swetland@google.com> Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
Diffstat (limited to 'arch/arm/mach-msm/smd.c')
-rw-r--r--arch/arm/mach-msm/smd.c425
1 files changed, 21 insertions, 404 deletions
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index b5f8957725de..1aaee4d70863 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -46,8 +46,7 @@ enum {
46 46
47static int msm_smd_debug_mask; 47static int msm_smd_debug_mask;
48 48
49struct shared_info 49struct shared_info {
50{
51 int ready; 50 int ready;
52 unsigned state; 51 unsigned state;
53}; 52};
@@ -61,8 +60,7 @@ static struct shared_info smd_info = {
61module_param_named(debug_mask, msm_smd_debug_mask, 60module_param_named(debug_mask, msm_smd_debug_mask,
62 int, S_IRUGO | S_IWUSR | S_IWGRP); 61 int, S_IRUGO | S_IWUSR | S_IWGRP);
63 62
64void *smem_find(unsigned id, unsigned size); 63void *smem_item(unsigned id, unsigned *size);
65static void *smem_item(unsigned id, unsigned *size);
66static void smd_diag(void); 64static void smd_diag(void);
67 65
68static unsigned last_heap_free = 0xffffffff; 66static unsigned last_heap_free = 0xffffffff;
@@ -126,114 +124,27 @@ static int check_for_modem_crash(void)
126 return 0; 124 return 0;
127} 125}
128 126
129#define SMD_SS_CLOSED 0x00000000
130#define SMD_SS_OPENING 0x00000001
131#define SMD_SS_OPENED 0x00000002
132#define SMD_SS_FLUSHING 0x00000003
133#define SMD_SS_CLOSING 0x00000004
134#define SMD_SS_RESET 0x00000005
135#define SMD_SS_RESET_OPENING 0x00000006
136
137#define SMD_BUF_SIZE 8192
138#define SMD_CHANNELS 64
139
140#define SMD_HEADER_SIZE 20
141
142
143/* the spinlock is used to synchronize between the 127/* the spinlock is used to synchronize between the
144** irq handler and code that mutates the channel 128 * irq handler and code that mutates the channel
145** list or fiddles with channel state 129 * list or fiddles with channel state
146*/ 130 */
147static DEFINE_SPINLOCK(smd_lock); 131DEFINE_SPINLOCK(smd_lock);
148static DEFINE_SPINLOCK(smem_lock); 132DEFINE_SPINLOCK(smem_lock);
149 133
150/* the mutex is used during open() and close() 134/* the mutex is used during open() and close()
151** operations to avoid races while creating or 135 * operations to avoid races while creating or
152** destroying smd_channel structures 136 * destroying smd_channel structures
153*/ 137 */
154static DEFINE_MUTEX(smd_creation_mutex); 138static DEFINE_MUTEX(smd_creation_mutex);
155 139
156static int smd_initialized; 140static int smd_initialized;
157 141
158struct smd_alloc_elm { 142LIST_HEAD(smd_ch_closed_list);
159 char name[20]; 143LIST_HEAD(smd_ch_list); /* todo: per-target lists */
160 uint32_t cid;
161 uint32_t ctype;
162 uint32_t ref_count;
163};
164
165struct smd_half_channel {
166 unsigned state;
167 unsigned char fDSR;
168 unsigned char fCTS;
169 unsigned char fCD;
170 unsigned char fRI;
171 unsigned char fHEAD;
172 unsigned char fTAIL;
173 unsigned char fSTATE;
174 unsigned char fUNUSED;
175 unsigned tail;
176 unsigned head;
177} __attribute__((packed));
178
179struct smd_shared_v1 {
180 struct smd_half_channel ch0;
181 unsigned char data0[SMD_BUF_SIZE];
182 struct smd_half_channel ch1;
183 unsigned char data1[SMD_BUF_SIZE];
184};
185
186struct smd_shared_v2 {
187 struct smd_half_channel ch0;
188 struct smd_half_channel ch1;
189};
190
191struct smd_channel {
192 volatile struct smd_half_channel *send;
193 volatile struct smd_half_channel *recv;
194 unsigned char *send_data;
195 unsigned char *recv_data;
196
197 unsigned fifo_mask;
198 unsigned fifo_size;
199 unsigned current_packet;
200 unsigned n;
201
202 struct list_head ch_list;
203
204 void *priv;
205 void (*notify)(void *priv, unsigned flags);
206
207 int (*read)(smd_channel_t *ch, void *data, int len);
208 int (*write)(smd_channel_t *ch, const void *data, int len);
209 int (*read_avail)(smd_channel_t *ch);
210 int (*write_avail)(smd_channel_t *ch);
211
212 void (*update_state)(smd_channel_t *ch);
213 unsigned last_state;
214 void (*notify_other_cpu)(void);
215 unsigned type;
216
217 char name[32];
218 struct platform_device pdev;
219};
220
221static LIST_HEAD(smd_ch_closed_list);
222static LIST_HEAD(smd_ch_list); /* todo: per-target lists */
223 144
224static unsigned char smd_ch_allocated[64]; 145static unsigned char smd_ch_allocated[64];
225static struct work_struct probe_work; 146static struct work_struct probe_work;
226 147
227#define SMD_TYPE_MASK 0x0FF
228#define SMD_TYPE_APPS_MODEM 0x000
229#define SMD_TYPE_APPS_DSP 0x001
230#define SMD_TYPE_MODEM_DSP 0x002
231
232#define SMD_KIND_MASK 0xF00
233#define SMD_KIND_UNKNOWN 0x000
234#define SMD_KIND_STREAM 0x100
235#define SMD_KIND_PACKET 0x200
236
237static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); 148static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type);
238 149
239static void smd_channel_probe_worker(struct work_struct *work) 150static void smd_channel_probe_worker(struct work_struct *work)
@@ -264,28 +175,6 @@ static void smd_channel_probe_worker(struct work_struct *work)
264 } 175 }
265} 176}
266 177
267static char *chstate(unsigned n)
268{
269 switch (n) {
270 case SMD_SS_CLOSED:
271 return "CLOSED";
272 case SMD_SS_OPENING:
273 return "OPENING";
274 case SMD_SS_OPENED:
275 return "OPENED";
276 case SMD_SS_FLUSHING:
277 return "FLUSHING";
278 case SMD_SS_CLOSING:
279 return "CLOSING";
280 case SMD_SS_RESET:
281 return "RESET";
282 case SMD_SS_RESET_OPENING:
283 return "ROPENING";
284 default:
285 return "UNKNOWN";
286 }
287}
288
289/* how many bytes are available for reading */ 178/* how many bytes are available for reading */
290static int smd_stream_read_avail(struct smd_channel *ch) 179static int smd_stream_read_avail(struct smd_channel *ch)
291{ 180{
@@ -345,9 +234,9 @@ static void ch_read_done(struct smd_channel *ch, unsigned count)
345} 234}
346 235
347/* basic read interface to ch_read_{buffer,done} used 236/* basic read interface to ch_read_{buffer,done} used
348** by smd_*_read() and update_packet_state() 237 * by smd_*_read() and update_packet_state()
349** will read-and-discard if the _data pointer is null 238 * will read-and-discard if the _data pointer is null
350*/ 239 */
351static int ch_read(struct smd_channel *ch, void *_data, int len) 240static int ch_read(struct smd_channel *ch, void *_data, int len)
352{ 241{
353 void *ptr; 242 void *ptr;
@@ -454,8 +343,7 @@ static void smd_state_change(struct smd_channel *ch,
454{ 343{
455 ch->last_state = next; 344 ch->last_state = next;
456 345
457 pr_info("SMD: ch %d %s -> %s\n", ch->n, 346 pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next);
458 chstate(last), chstate(next));
459 347
460 switch (next) { 348 switch (next) {
461 case SMD_SS_OPENING: 349 case SMD_SS_OPENING:
@@ -936,7 +824,7 @@ void *smem_alloc(unsigned id, unsigned size)
936 return smem_find(id, size); 824 return smem_find(id, size);
937} 825}
938 826
939static void *smem_item(unsigned id, unsigned *size) 827void *smem_item(unsigned id, unsigned *size)
940{ 828{
941 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; 829 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
942 struct smem_heap_entry *toc = shared->heap_toc; 830 struct smem_heap_entry *toc = shared->heap_toc;
@@ -1042,8 +930,9 @@ uint32_t smsm_get_state(enum smsm_state_item item)
1042 930
1043int smsm_set_sleep_duration(uint32_t delay) 931int smsm_set_sleep_duration(uint32_t delay)
1044{ 932{
1045 struct msm_dem_slave_data *ptr = smem_alloc(SMEM_APPS_DEM_SLAVE_DATA, 933 struct msm_dem_slave_data *ptr;
1046 sizeof(*ptr)); 934
935 ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr));
1047 if (ptr == NULL) { 936 if (ptr == NULL) {
1048 pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n"); 937 pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n");
1049 return -EIO; 938 return -EIO;
@@ -1061,7 +950,7 @@ int smsm_set_sleep_duration(uint32_t delay)
1061{ 950{
1062 uint32_t *ptr; 951 uint32_t *ptr;
1063 952
1064 ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); 953 ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
1065 if (ptr == NULL) { 954 if (ptr == NULL) {
1066 pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n"); 955 pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
1067 return -EIO; 956 return -EIO;
@@ -1075,76 +964,6 @@ int smsm_set_sleep_duration(uint32_t delay)
1075 964
1076#endif 965#endif
1077 966
1078#define MAX_NUM_SLEEP_CLIENTS 64
1079#define MAX_SLEEP_NAME_LEN 8
1080
1081#define NUM_GPIO_INT_REGISTERS 6
1082#define GPIO_SMEM_NUM_GROUPS 2
1083#define GPIO_SMEM_MAX_PC_INTERRUPTS 8
1084
1085struct tramp_gpio_save {
1086 unsigned int enable;
1087 unsigned int detect;
1088 unsigned int polarity;
1089};
1090
1091struct tramp_gpio_smem {
1092 uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
1093 uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
1094 uint32_t enabled[NUM_GPIO_INT_REGISTERS];
1095 uint32_t detection[NUM_GPIO_INT_REGISTERS];
1096 uint32_t polarity[NUM_GPIO_INT_REGISTERS];
1097};
1098
1099
1100void smsm_print_sleep_info(void)
1101{
1102 unsigned long flags;
1103 uint32_t *ptr;
1104 struct tramp_gpio_smem *gpio;
1105 struct smsm_interrupt_info *int_info;
1106
1107
1108 spin_lock_irqsave(&smem_lock, flags);
1109
1110 ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
1111 if (ptr)
1112 pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr);
1113
1114 ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr));
1115 if (ptr)
1116 pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr);
1117
1118 ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr));
1119 if (ptr)
1120 pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr);
1121
1122#ifndef CONFIG_ARCH_MSM_SCORPION
1123 int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info));
1124 if (int_info)
1125 pr_info("SMEM_SMSM_INT_INFO %x %x %x\n",
1126 int_info->interrupt_mask,
1127 int_info->pending_interrupts,
1128 int_info->wakeup_reason);
1129
1130 gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio));
1131 if (gpio) {
1132 int i;
1133 for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++)
1134 pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n",
1135 i, gpio->enabled[i], gpio->detection[i],
1136 gpio->polarity[i]);
1137
1138 for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
1139 pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n",
1140 i, gpio->num_fired[i], gpio->fired[i][0],
1141 gpio->fired[i][1]);
1142 }
1143#else
1144#endif
1145 spin_unlock_irqrestore(&smem_lock, flags);
1146}
1147
1148int smd_core_init(void) 967int smd_core_init(void)
1149{ 968{
1150 int r; 969 int r;
@@ -1196,207 +1015,6 @@ int smd_core_init(void)
1196 return 0; 1015 return 0;
1197} 1016}
1198 1017
1199#if defined(CONFIG_DEBUG_FS)
1200
1201static int dump_ch(char *buf, int max, struct smd_channel *ch)
1202{
1203 volatile struct smd_half_channel *s = ch->send;
1204 volatile struct smd_half_channel *r = ch->recv;
1205
1206 return scnprintf(
1207 buf, max,
1208 "ch%02d:"
1209 " %8s(%05d/%05d) %c%c%c%c%c%c%c <->"
1210 " %8s(%05d/%05d) %c%c%c%c%c%c%c\n", ch->n,
1211 chstate(s->state), s->tail, s->head,
1212 s->fDSR ? 'D' : 'd',
1213 s->fCTS ? 'C' : 'c',
1214 s->fCD ? 'C' : 'c',
1215 s->fRI ? 'I' : 'i',
1216 s->fHEAD ? 'W' : 'w',
1217 s->fTAIL ? 'R' : 'r',
1218 s->fSTATE ? 'S' : 's',
1219 chstate(r->state), r->tail, r->head,
1220 r->fDSR ? 'D' : 'd',
1221 r->fCTS ? 'R' : 'r',
1222 r->fCD ? 'C' : 'c',
1223 r->fRI ? 'I' : 'i',
1224 r->fHEAD ? 'W' : 'w',
1225 r->fTAIL ? 'R' : 'r',
1226 r->fSTATE ? 'S' : 's'
1227 );
1228}
1229
1230static int debug_read_stat(char *buf, int max)
1231{
1232 char *msg;
1233 int i = 0;
1234
1235 msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
1236
1237 if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
1238 i += scnprintf(buf + i, max - i,
1239 "smsm: ARM9 HAS CRASHED\n");
1240
1241 i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n",
1242 raw_smsm_get_state(SMSM_STATE_MODEM),
1243 raw_smsm_get_state(SMSM_STATE_APPS));
1244#ifdef CONFIG_ARCH_MSM_SCORPION
1245 i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x "
1246 "qdsp6: %08x power: %08x time: %08x\n",
1247 raw_smsm_get_state(SMSM_STATE_APPS_DEM),
1248 raw_smsm_get_state(SMSM_STATE_MODEM_DEM),
1249 raw_smsm_get_state(SMSM_STATE_QDSP6_DEM),
1250 raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM),
1251 raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM));
1252#endif
1253 if (msg) {
1254 msg[SZ_DIAG_ERR_MSG - 1] = 0;
1255 i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg);
1256 }
1257 return i;
1258}
1259
1260static int debug_read_mem(char *buf, int max)
1261{
1262 unsigned n;
1263 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
1264 struct smem_heap_entry *toc = shared->heap_toc;
1265 int i = 0;
1266
1267 i += scnprintf(buf + i, max - i,
1268 "heap: init=%d free=%d remain=%d\n",
1269 shared->heap_info.initialized,
1270 shared->heap_info.free_offset,
1271 shared->heap_info.heap_remaining);
1272
1273 for (n = 0; n < SMEM_NUM_ITEMS; n++) {
1274 if (toc[n].allocated == 0)
1275 continue;
1276 i += scnprintf(buf + i, max - i,
1277 "%04d: offset %08x size %08x\n",
1278 n, toc[n].offset, toc[n].size);
1279 }
1280 return i;
1281}
1282
1283static int debug_read_ch(char *buf, int max)
1284{
1285 struct smd_channel *ch;
1286 unsigned long flags;
1287 int i = 0;
1288
1289 spin_lock_irqsave(&smd_lock, flags);
1290 list_for_each_entry(ch, &smd_ch_list, ch_list)
1291 i += dump_ch(buf + i, max - i, ch);
1292 list_for_each_entry(ch, &smd_ch_closed_list, ch_list)
1293 i += dump_ch(buf + i, max - i, ch);
1294 spin_unlock_irqrestore(&smd_lock, flags);
1295
1296 return i;
1297}
1298
1299static int debug_read_version(char *buf, int max)
1300{
1301 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
1302 unsigned version = shared->version[VERSION_MODEM];
1303 return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff);
1304}
1305
1306static int debug_read_build_id(char *buf, int max)
1307{
1308 unsigned size;
1309 void *data;
1310
1311 data = smem_item(SMEM_HW_SW_BUILD_ID, &size);
1312 if (!data)
1313 return 0;
1314
1315 if (size >= max)
1316 size = max;
1317 memcpy(buf, data, size);
1318
1319 return size;
1320}
1321
1322static int debug_read_alloc_tbl(char *buf, int max)
1323{
1324 struct smd_alloc_elm *shared;
1325 int n, i = 0;
1326
1327 shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
1328
1329 for (n = 0; n < 64; n++) {
1330 if (shared[n].ref_count == 0)
1331 continue;
1332 i += scnprintf(buf + i, max - i,
1333 "%03d: %-20s cid=%02d type=%03d "
1334 "kind=%02d ref_count=%d\n",
1335 n, shared[n].name, shared[n].cid,
1336 shared[n].ctype & 0xff,
1337 (shared[n].ctype >> 8) & 0xf,
1338 shared[n].ref_count);
1339 }
1340
1341 return i;
1342}
1343
1344static int debug_boom(char *buf, int max)
1345{
1346 unsigned ms = 5000;
1347 msm_proc_comm(PCOM_RESET_MODEM, &ms, 0);
1348 return 0;
1349}
1350
1351#define DEBUG_BUFMAX 4096
1352static char debug_buffer[DEBUG_BUFMAX];
1353
1354static ssize_t debug_read(struct file *file, char __user *buf,
1355 size_t count, loff_t *ppos)
1356{
1357 int (*fill)(char *buf, int max) = file->private_data;
1358 int bsize = fill(debug_buffer, DEBUG_BUFMAX);
1359 return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
1360}
1361
1362static int debug_open(struct inode *inode, struct file *file)
1363{
1364 file->private_data = inode->i_private;
1365 return 0;
1366}
1367
1368static const struct file_operations debug_ops = {
1369 .read = debug_read,
1370 .open = debug_open,
1371};
1372
1373static void debug_create(const char *name, mode_t mode,
1374 struct dentry *dent,
1375 int (*fill)(char *buf, int max))
1376{
1377 debugfs_create_file(name, mode, dent, fill, &debug_ops);
1378}
1379
1380static void smd_debugfs_init(void)
1381{
1382 struct dentry *dent;
1383
1384 dent = debugfs_create_dir("smd", 0);
1385 if (IS_ERR(dent))
1386 return;
1387
1388 debug_create("ch", 0444, dent, debug_read_ch);
1389 debug_create("stat", 0444, dent, debug_read_stat);
1390 debug_create("mem", 0444, dent, debug_read_mem);
1391 debug_create("version", 0444, dent, debug_read_version);
1392 debug_create("tbl", 0444, dent, debug_read_alloc_tbl);
1393 debug_create("build", 0444, dent, debug_read_build_id);
1394 debug_create("boom", 0444, dent, debug_boom);
1395}
1396#else
1397static void smd_debugfs_init(void) {}
1398#endif
1399
1400static int __init msm_smd_probe(struct platform_device *pdev) 1018static int __init msm_smd_probe(struct platform_device *pdev)
1401{ 1019{
1402 pr_info("smd_init()\n"); 1020 pr_info("smd_init()\n");
@@ -1412,7 +1030,6 @@ static int __init msm_smd_probe(struct platform_device *pdev)
1412 1030
1413 msm_check_for_modem_crash = check_for_modem_crash; 1031 msm_check_for_modem_crash = check_for_modem_crash;
1414 1032
1415 smd_debugfs_init();
1416 smd_initialized = 1; 1033 smd_initialized = 1;
1417 1034
1418 return 0; 1035 return 0;