diff options
Diffstat (limited to 'arch/arm/mach-omap2/mailbox.c')
-rw-r--r-- | arch/arm/mach-omap2/mailbox.c | 111 |
1 files changed, 30 insertions, 81 deletions
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 42dbfa46e656..86d564a640bb 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c | |||
@@ -14,12 +14,11 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/pm_runtime.h> | ||
17 | #include <plat/mailbox.h> | 18 | #include <plat/mailbox.h> |
18 | #include <mach/irqs.h> | 19 | #include <mach/irqs.h> |
19 | 20 | ||
20 | #define MAILBOX_REVISION 0x000 | 21 | #define MAILBOX_REVISION 0x000 |
21 | #define MAILBOX_SYSCONFIG 0x010 | ||
22 | #define MAILBOX_SYSSTATUS 0x014 | ||
23 | #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m)) | 22 | #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m)) |
24 | #define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m)) | 23 | #define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m)) |
25 | #define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m)) | 24 | #define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m)) |
@@ -33,17 +32,6 @@ | |||
33 | #define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m))) | 32 | #define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m))) |
34 | #define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1)) | 33 | #define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1)) |
35 | 34 | ||
36 | /* SYSCONFIG: register bit definition */ | ||
37 | #define AUTOIDLE (1 << 0) | ||
38 | #define SOFTRESET (1 << 1) | ||
39 | #define SMARTIDLE (2 << 3) | ||
40 | #define OMAP4_SOFTRESET (1 << 0) | ||
41 | #define OMAP4_NOIDLE (1 << 2) | ||
42 | #define OMAP4_SMARTIDLE (2 << 2) | ||
43 | |||
44 | /* SYSSTATUS: register bit definition */ | ||
45 | #define RESETDONE (1 << 0) | ||
46 | |||
47 | #define MBOX_REG_SIZE 0x120 | 35 | #define MBOX_REG_SIZE 0x120 |
48 | 36 | ||
49 | #define OMAP4_MBOX_REG_SIZE 0x130 | 37 | #define OMAP4_MBOX_REG_SIZE 0x130 |
@@ -70,8 +58,6 @@ struct omap_mbox2_priv { | |||
70 | unsigned long irqdisable; | 58 | unsigned long irqdisable; |
71 | }; | 59 | }; |
72 | 60 | ||
73 | static struct clk *mbox_ick_handle; | ||
74 | |||
75 | static void omap2_mbox_enable_irq(struct omap_mbox *mbox, | 61 | static void omap2_mbox_enable_irq(struct omap_mbox *mbox, |
76 | omap_mbox_type_t irq); | 62 | omap_mbox_type_t irq); |
77 | 63 | ||
@@ -89,53 +75,13 @@ static inline void mbox_write_reg(u32 val, size_t ofs) | |||
89 | static int omap2_mbox_startup(struct omap_mbox *mbox) | 75 | static int omap2_mbox_startup(struct omap_mbox *mbox) |
90 | { | 76 | { |
91 | u32 l; | 77 | u32 l; |
92 | unsigned long timeout; | ||
93 | 78 | ||
94 | mbox_ick_handle = clk_get(NULL, "mailboxes_ick"); | 79 | pm_runtime_enable(mbox->dev->parent); |
95 | if (IS_ERR(mbox_ick_handle)) { | 80 | pm_runtime_get_sync(mbox->dev->parent); |
96 | printk(KERN_ERR "Could not get mailboxes_ick: %ld\n", | ||
97 | PTR_ERR(mbox_ick_handle)); | ||
98 | return PTR_ERR(mbox_ick_handle); | ||
99 | } | ||
100 | clk_enable(mbox_ick_handle); | ||
101 | |||
102 | if (cpu_is_omap44xx()) { | ||
103 | mbox_write_reg(OMAP4_SOFTRESET, MAILBOX_SYSCONFIG); | ||
104 | timeout = jiffies + msecs_to_jiffies(20); | ||
105 | do { | ||
106 | l = mbox_read_reg(MAILBOX_SYSCONFIG); | ||
107 | if (!(l & OMAP4_SOFTRESET)) | ||
108 | break; | ||
109 | } while (!time_after(jiffies, timeout)); | ||
110 | |||
111 | if (l & OMAP4_SOFTRESET) { | ||
112 | pr_err("Can't take mailbox out of reset\n"); | ||
113 | return -ENODEV; | ||
114 | } | ||
115 | } else { | ||
116 | mbox_write_reg(SOFTRESET, MAILBOX_SYSCONFIG); | ||
117 | timeout = jiffies + msecs_to_jiffies(20); | ||
118 | do { | ||
119 | l = mbox_read_reg(MAILBOX_SYSSTATUS); | ||
120 | if (l & RESETDONE) | ||
121 | break; | ||
122 | } while (!time_after(jiffies, timeout)); | ||
123 | |||
124 | if (!(l & RESETDONE)) { | ||
125 | pr_err("Can't take mailbox out of reset\n"); | ||
126 | return -ENODEV; | ||
127 | } | ||
128 | } | ||
129 | 81 | ||
130 | l = mbox_read_reg(MAILBOX_REVISION); | 82 | l = mbox_read_reg(MAILBOX_REVISION); |
131 | pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); | 83 | pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); |
132 | 84 | ||
133 | if (cpu_is_omap44xx()) | ||
134 | l = OMAP4_SMARTIDLE; | ||
135 | else | ||
136 | l = SMARTIDLE | AUTOIDLE; | ||
137 | mbox_write_reg(l, MAILBOX_SYSCONFIG); | ||
138 | |||
139 | omap2_mbox_enable_irq(mbox, IRQ_RX); | 85 | omap2_mbox_enable_irq(mbox, IRQ_RX); |
140 | 86 | ||
141 | return 0; | 87 | return 0; |
@@ -143,9 +89,8 @@ static int omap2_mbox_startup(struct omap_mbox *mbox) | |||
143 | 89 | ||
144 | static void omap2_mbox_shutdown(struct omap_mbox *mbox) | 90 | static void omap2_mbox_shutdown(struct omap_mbox *mbox) |
145 | { | 91 | { |
146 | clk_disable(mbox_ick_handle); | 92 | pm_runtime_put_sync(mbox->dev->parent); |
147 | clk_put(mbox_ick_handle); | 93 | pm_runtime_disable(mbox->dev->parent); |
148 | mbox_ick_handle = NULL; | ||
149 | } | 94 | } |
150 | 95 | ||
151 | /* Mailbox FIFO handle functions */ | 96 | /* Mailbox FIFO handle functions */ |
@@ -181,7 +126,7 @@ static int omap2_mbox_fifo_full(struct omap_mbox *mbox) | |||
181 | static void omap2_mbox_enable_irq(struct omap_mbox *mbox, | 126 | static void omap2_mbox_enable_irq(struct omap_mbox *mbox, |
182 | omap_mbox_type_t irq) | 127 | omap_mbox_type_t irq) |
183 | { | 128 | { |
184 | struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; | 129 | struct omap_mbox2_priv *p = mbox->priv; |
185 | u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; | 130 | u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; |
186 | 131 | ||
187 | l = mbox_read_reg(p->irqenable); | 132 | l = mbox_read_reg(p->irqenable); |
@@ -192,17 +137,19 @@ static void omap2_mbox_enable_irq(struct omap_mbox *mbox, | |||
192 | static void omap2_mbox_disable_irq(struct omap_mbox *mbox, | 137 | static void omap2_mbox_disable_irq(struct omap_mbox *mbox, |
193 | omap_mbox_type_t irq) | 138 | omap_mbox_type_t irq) |
194 | { | 139 | { |
195 | struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; | 140 | struct omap_mbox2_priv *p = mbox->priv; |
196 | u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; | 141 | u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; |
197 | l = mbox_read_reg(p->irqdisable); | 142 | |
198 | l &= ~bit; | 143 | if (!cpu_is_omap44xx()) |
199 | mbox_write_reg(l, p->irqdisable); | 144 | bit = mbox_read_reg(p->irqdisable) & ~bit; |
145 | |||
146 | mbox_write_reg(bit, p->irqdisable); | ||
200 | } | 147 | } |
201 | 148 | ||
202 | static void omap2_mbox_ack_irq(struct omap_mbox *mbox, | 149 | static void omap2_mbox_ack_irq(struct omap_mbox *mbox, |
203 | omap_mbox_type_t irq) | 150 | omap_mbox_type_t irq) |
204 | { | 151 | { |
205 | struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; | 152 | struct omap_mbox2_priv *p = mbox->priv; |
206 | u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; | 153 | u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; |
207 | 154 | ||
208 | mbox_write_reg(bit, p->irqstatus); | 155 | mbox_write_reg(bit, p->irqstatus); |
@@ -214,7 +161,7 @@ static void omap2_mbox_ack_irq(struct omap_mbox *mbox, | |||
214 | static int omap2_mbox_is_irq(struct omap_mbox *mbox, | 161 | static int omap2_mbox_is_irq(struct omap_mbox *mbox, |
215 | omap_mbox_type_t irq) | 162 | omap_mbox_type_t irq) |
216 | { | 163 | { |
217 | struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; | 164 | struct omap_mbox2_priv *p = mbox->priv; |
218 | u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; | 165 | u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; |
219 | u32 enable = mbox_read_reg(p->irqenable); | 166 | u32 enable = mbox_read_reg(p->irqenable); |
220 | u32 status = mbox_read_reg(p->irqstatus); | 167 | u32 status = mbox_read_reg(p->irqstatus); |
@@ -281,7 +228,7 @@ static struct omap_mbox_ops omap2_mbox_ops = { | |||
281 | 228 | ||
282 | /* FIXME: the following structs should be filled automatically by the user id */ | 229 | /* FIXME: the following structs should be filled automatically by the user id */ |
283 | 230 | ||
284 | #if defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_ARCH_OMAP2420) | 231 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP2) |
285 | /* DSP */ | 232 | /* DSP */ |
286 | static struct omap_mbox2_priv omap2_mbox_dsp_priv = { | 233 | static struct omap_mbox2_priv omap2_mbox_dsp_priv = { |
287 | .tx_fifo = { | 234 | .tx_fifo = { |
@@ -306,11 +253,11 @@ struct omap_mbox mbox_dsp_info = { | |||
306 | }; | 253 | }; |
307 | #endif | 254 | #endif |
308 | 255 | ||
309 | #if defined(CONFIG_ARCH_OMAP3430) | 256 | #if defined(CONFIG_ARCH_OMAP3) |
310 | struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL }; | 257 | struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL }; |
311 | #endif | 258 | #endif |
312 | 259 | ||
313 | #if defined(CONFIG_ARCH_OMAP2420) | 260 | #if defined(CONFIG_SOC_OMAP2420) |
314 | /* IVA */ | 261 | /* IVA */ |
315 | static struct omap_mbox2_priv omap2_mbox_iva_priv = { | 262 | static struct omap_mbox2_priv omap2_mbox_iva_priv = { |
316 | .tx_fifo = { | 263 | .tx_fifo = { |
@@ -334,7 +281,7 @@ static struct omap_mbox mbox_iva_info = { | |||
334 | .priv = &omap2_mbox_iva_priv, | 281 | .priv = &omap2_mbox_iva_priv, |
335 | }; | 282 | }; |
336 | 283 | ||
337 | struct omap_mbox *omap2_mboxes[] = { &mbox_iva_info, &mbox_dsp_info, NULL }; | 284 | struct omap_mbox *omap2_mboxes[] = { &mbox_dsp_info, &mbox_iva_info, NULL }; |
338 | #endif | 285 | #endif |
339 | 286 | ||
340 | #if defined(CONFIG_ARCH_OMAP4) | 287 | #if defined(CONFIG_ARCH_OMAP4) |
@@ -394,15 +341,19 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev) | |||
394 | 341 | ||
395 | if (false) | 342 | if (false) |
396 | ; | 343 | ; |
397 | #if defined(CONFIG_ARCH_OMAP3430) | 344 | #if defined(CONFIG_ARCH_OMAP3) |
398 | else if (cpu_is_omap3430()) { | 345 | else if (cpu_is_omap34xx()) { |
399 | list = omap3_mboxes; | 346 | list = omap3_mboxes; |
400 | 347 | ||
401 | list[0]->irq = platform_get_irq_byname(pdev, "dsp"); | 348 | list[0]->irq = platform_get_irq(pdev, 0); |
402 | } | 349 | } |
403 | #endif | 350 | #endif |
404 | #if defined(CONFIG_ARCH_OMAP2420) | 351 | #if defined(CONFIG_ARCH_OMAP2) |
405 | else if (cpu_is_omap2420()) { | 352 | else if (cpu_is_omap2430()) { |
353 | list = omap2_mboxes; | ||
354 | |||
355 | list[0]->irq = platform_get_irq(pdev, 0); | ||
356 | } else if (cpu_is_omap2420()) { | ||
406 | list = omap2_mboxes; | 357 | list = omap2_mboxes; |
407 | 358 | ||
408 | list[0]->irq = platform_get_irq_byname(pdev, "dsp"); | 359 | list[0]->irq = platform_get_irq_byname(pdev, "dsp"); |
@@ -413,8 +364,7 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev) | |||
413 | else if (cpu_is_omap44xx()) { | 364 | else if (cpu_is_omap44xx()) { |
414 | list = omap4_mboxes; | 365 | list = omap4_mboxes; |
415 | 366 | ||
416 | list[0]->irq = list[1]->irq = | 367 | list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0); |
417 | platform_get_irq_byname(pdev, "mbox"); | ||
418 | } | 368 | } |
419 | #endif | 369 | #endif |
420 | else { | 370 | else { |
@@ -432,9 +382,8 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev) | |||
432 | iounmap(mbox_base); | 382 | iounmap(mbox_base); |
433 | return ret; | 383 | return ret; |
434 | } | 384 | } |
435 | return 0; | ||
436 | 385 | ||
437 | return ret; | 386 | return 0; |
438 | } | 387 | } |
439 | 388 | ||
440 | static int __devexit omap2_mbox_remove(struct platform_device *pdev) | 389 | static int __devexit omap2_mbox_remove(struct platform_device *pdev) |