Commit | Line | Data |
---|---|---|
5f5bac82 MM |
1 | /* |
2 | * cb710/debug.c | |
3 | * | |
4 | * Copyright by Michał Mirosław, 2008-2009 | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | */ | |
10 | #include <linux/cb710.h> | |
11 | #include <linux/kernel.h> | |
12 | #include <linux/module.h> | |
5f5bac82 MM |
13 | |
14 | #define CB710_REG_COUNT 0x80 | |
15 | ||
16 | static const u16 allow[CB710_REG_COUNT/16] = { | |
17 | 0xFFF0, 0xFFFF, 0xFFFF, 0xFFFF, | |
18 | 0xFFF0, 0xFFFF, 0xFFFF, 0xFFFF, | |
19 | }; | |
20 | static const char *const prefix[ARRAY_SIZE(allow)] = { | |
21 | "MMC", "MMC", "MMC", "MMC", | |
22 | "MS?", "MS?", "SM?", "SM?" | |
23 | }; | |
24 | ||
25 | static inline int allow_reg_read(unsigned block, unsigned offset, unsigned bits) | |
26 | { | |
27 | unsigned mask = (1 << bits/8) - 1; | |
28 | offset *= bits/8; | |
29 | return ((allow[block] >> offset) & mask) == mask; | |
30 | } | |
31 | ||
32 | #define CB710_READ_REGS_TEMPLATE(t) \ | |
33 | static void cb710_read_regs_##t(void __iomem *iobase, \ | |
34 | u##t *reg, unsigned select) \ | |
35 | { \ | |
36 | unsigned i, j; \ | |
37 | \ | |
38 | for (i = 0; i < ARRAY_SIZE(allow); ++i, reg += 16/(t/8)) { \ | |
10eb4f90 | 39 | if (!(select & (1 << i))) \ |
5f5bac82 MM |
40 | continue; \ |
41 | \ | |
42 | for (j = 0; j < 0x10/(t/8); ++j) { \ | |
43 | if (!allow_reg_read(i, j, t)) \ | |
44 | continue; \ | |
45 | reg[j] = ioread##t(iobase \ | |
46 | + (i << 4) + (j * (t/8))); \ | |
47 | } \ | |
48 | } \ | |
49 | } | |
50 | ||
51 | static const char cb710_regf_8[] = "%02X"; | |
52 | static const char cb710_regf_16[] = "%04X"; | |
53 | static const char cb710_regf_32[] = "%08X"; | |
54 | static const char cb710_xes[] = "xxxxxxxx"; | |
55 | ||
56 | #define CB710_DUMP_REGS_TEMPLATE(t) \ | |
57 | static void cb710_dump_regs_##t(struct device *dev, \ | |
58 | const u##t *reg, unsigned select) \ | |
59 | { \ | |
60 | const char *const xp = &cb710_xes[8 - t/4]; \ | |
61 | const char *const format = cb710_regf_##t; \ | |
62 | \ | |
63 | char msg[100], *p; \ | |
64 | unsigned i, j; \ | |
65 | \ | |
66 | for (i = 0; i < ARRAY_SIZE(allow); ++i, reg += 16/(t/8)) { \ | |
67 | if (!(select & (1 << i))) \ | |
68 | continue; \ | |
69 | p = msg; \ | |
70 | for (j = 0; j < 0x10/(t/8); ++j) { \ | |
71 | *p++ = ' '; \ | |
72 | if (j == 8/(t/8)) \ | |
73 | *p++ = ' '; \ | |
74 | if (allow_reg_read(i, j, t)) \ | |
75 | p += sprintf(p, format, reg[j]); \ | |
76 | else \ | |
77 | p += sprintf(p, "%s", xp); \ | |
78 | } \ | |
79 | dev_dbg(dev, "%s 0x%02X %s\n", prefix[i], i << 4, msg); \ | |
80 | } \ | |
81 | } | |
82 | ||
83 | #define CB710_READ_AND_DUMP_REGS_TEMPLATE(t) \ | |
84 | static void cb710_read_and_dump_regs_##t(struct cb710_chip *chip, \ | |
85 | unsigned select) \ | |
86 | { \ | |
87 | u##t regs[CB710_REG_COUNT/sizeof(u##t)]; \ | |
88 | \ | |
89 | memset(®s, 0, sizeof(regs)); \ | |
90 | cb710_read_regs_##t(chip->iobase, regs, select); \ | |
91 | cb710_dump_regs_##t(cb710_chip_dev(chip), regs, select); \ | |
92 | } | |
93 | ||
94 | #define CB710_REG_ACCESS_TEMPLATES(t) \ | |
95 | CB710_READ_REGS_TEMPLATE(t) \ | |
96 | CB710_DUMP_REGS_TEMPLATE(t) \ | |
97 | CB710_READ_AND_DUMP_REGS_TEMPLATE(t) | |
98 | ||
99 | CB710_REG_ACCESS_TEMPLATES(8) | |
100 | CB710_REG_ACCESS_TEMPLATES(16) | |
101 | CB710_REG_ACCESS_TEMPLATES(32) | |
102 | ||
103 | void cb710_dump_regs(struct cb710_chip *chip, unsigned select) | |
104 | { | |
105 | if (!(select & CB710_DUMP_REGS_MASK)) | |
106 | select = CB710_DUMP_REGS_ALL; | |
107 | if (!(select & CB710_DUMP_ACCESS_MASK)) | |
108 | select |= CB710_DUMP_ACCESS_8; | |
109 | ||
110 | if (select & CB710_DUMP_ACCESS_32) | |
111 | cb710_read_and_dump_regs_32(chip, select); | |
112 | if (select & CB710_DUMP_ACCESS_16) | |
113 | cb710_read_and_dump_regs_16(chip, select); | |
114 | if (select & CB710_DUMP_ACCESS_8) | |
115 | cb710_read_and_dump_regs_8(chip, select); | |
116 | } | |
117 | EXPORT_SYMBOL_GPL(cb710_dump_regs); | |
118 |