This source file includes following definitions.
- sh4a_ubc_enable
- sh4a_ubc_disable
- sh4a_ubc_enable_all
- sh4a_ubc_disable_all
- sh4a_ubc_active_mask
- sh4a_ubc_triggered_mask
- sh4a_ubc_clear_triggered_mask
- sh4a_ubc_init
1
2
3
4
5
6
7
8
9 #include <linux/init.h>
10 #include <linux/err.h>
11 #include <linux/clk.h>
12 #include <linux/io.h>
13 #include <asm/hw_breakpoint.h>
14
15 #define UBC_CBR(idx) (0xff200000 + (0x20 * idx))
16 #define UBC_CRR(idx) (0xff200004 + (0x20 * idx))
17 #define UBC_CAR(idx) (0xff200008 + (0x20 * idx))
18 #define UBC_CAMR(idx) (0xff20000c + (0x20 * idx))
19
20 #define UBC_CCMFR 0xff200600
21 #define UBC_CBCR 0xff200620
22
23
24 #define UBC_CRR_PCB (1 << 1)
25 #define UBC_CRR_BIE (1 << 0)
26
27
28 #define UBC_CBR_CE (1 << 0)
29
30 static struct sh_ubc sh4a_ubc;
31
32 static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
33 {
34 __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
35 __raw_writel(info->address, UBC_CAR(idx));
36 }
37
38 static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
39 {
40 __raw_writel(0, UBC_CBR(idx));
41 __raw_writel(0, UBC_CAR(idx));
42 }
43
44 static void sh4a_ubc_enable_all(unsigned long mask)
45 {
46 int i;
47
48 for (i = 0; i < sh4a_ubc.num_events; i++)
49 if (mask & (1 << i))
50 __raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
51 UBC_CBR(i));
52 }
53
54 static void sh4a_ubc_disable_all(void)
55 {
56 int i;
57
58 for (i = 0; i < sh4a_ubc.num_events; i++)
59 __raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
60 UBC_CBR(i));
61 }
62
63 static unsigned long sh4a_ubc_active_mask(void)
64 {
65 unsigned long active = 0;
66 int i;
67
68 for (i = 0; i < sh4a_ubc.num_events; i++)
69 if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
70 active |= (1 << i);
71
72 return active;
73 }
74
75 static unsigned long sh4a_ubc_triggered_mask(void)
76 {
77 return __raw_readl(UBC_CCMFR);
78 }
79
80 static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
81 {
82 __raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
83 }
84
85 static struct sh_ubc sh4a_ubc = {
86 .name = "SH-4A",
87 .num_events = 2,
88 .trap_nr = 0x1e0,
89 .enable = sh4a_ubc_enable,
90 .disable = sh4a_ubc_disable,
91 .enable_all = sh4a_ubc_enable_all,
92 .disable_all = sh4a_ubc_disable_all,
93 .active_mask = sh4a_ubc_active_mask,
94 .triggered_mask = sh4a_ubc_triggered_mask,
95 .clear_triggered_mask = sh4a_ubc_clear_triggered_mask,
96 };
97
98 static int __init sh4a_ubc_init(void)
99 {
100 struct clk *ubc_iclk = clk_get(NULL, "ubc0");
101 int i;
102
103
104
105
106
107 if (IS_ERR(ubc_iclk))
108 ubc_iclk = NULL;
109
110 clk_enable(ubc_iclk);
111
112 __raw_writel(0, UBC_CBCR);
113
114 for (i = 0; i < sh4a_ubc.num_events; i++) {
115 __raw_writel(0, UBC_CAMR(i));
116 __raw_writel(0, UBC_CBR(i));
117
118 __raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i));
119
120
121 (void)__raw_readl(UBC_CRR(i));
122 }
123
124 clk_disable(ubc_iclk);
125
126 sh4a_ubc.clk = ubc_iclk;
127
128 return register_sh_ubc(&sh4a_ubc);
129 }
130 arch_initcall(sh4a_ubc_init);