summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mailbox/omap-mailbox.c126
1 files changed, 63 insertions, 63 deletions
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index 66b02ab00b19..d9a503974d52 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -69,18 +69,10 @@ struct omap_mbox_fifo {
69 unsigned long msg; 69 unsigned long msg;
70 unsigned long fifo_stat; 70 unsigned long fifo_stat;
71 unsigned long msg_stat; 71 unsigned long msg_stat;
72};
73
74struct omap_mbox_priv {
75 struct omap_mbox_fifo tx_fifo;
76 struct omap_mbox_fifo rx_fifo;
77 unsigned long irqenable; 72 unsigned long irqenable;
78 unsigned long irqstatus; 73 unsigned long irqstatus;
79 u32 newmsg_bit;
80 u32 notfull_bit;
81 u32 ctx[OMAP4_MBOX_NR_REGS];
82 unsigned long irqdisable; 74 unsigned long irqdisable;
83 u32 intr_type; 75 u32 intr_bit;
84}; 76};
85 77
86struct omap_mbox_queue { 78struct omap_mbox_queue {
@@ -97,7 +89,10 @@ struct omap_mbox {
97 int irq; 89 int irq;
98 struct omap_mbox_queue *txq, *rxq; 90 struct omap_mbox_queue *txq, *rxq;
99 struct device *dev; 91 struct device *dev;
100 void *priv; 92 struct omap_mbox_fifo tx_fifo;
93 struct omap_mbox_fifo rx_fifo;
94 u32 ctx[OMAP4_MBOX_NR_REGS];
95 u32 intr_type;
101 int use_count; 96 int use_count;
102 struct blocking_notifier_head notifier; 97 struct blocking_notifier_head notifier;
103}; 98};
@@ -124,50 +119,52 @@ static inline void mbox_write_reg(u32 val, size_t ofs)
124/* Mailbox FIFO handle functions */ 119/* Mailbox FIFO handle functions */
125static mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) 120static mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
126{ 121{
127 struct omap_mbox_fifo *fifo = 122 struct omap_mbox_fifo *fifo = &mbox->rx_fifo;
128 &((struct omap_mbox_priv *)mbox->priv)->rx_fifo;
129 return (mbox_msg_t) mbox_read_reg(fifo->msg); 123 return (mbox_msg_t) mbox_read_reg(fifo->msg);
130} 124}
131 125
132static void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) 126static void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
133{ 127{
134 struct omap_mbox_fifo *fifo = 128 struct omap_mbox_fifo *fifo = &mbox->tx_fifo;
135 &((struct omap_mbox_priv *)mbox->priv)->tx_fifo;
136 mbox_write_reg(msg, fifo->msg); 129 mbox_write_reg(msg, fifo->msg);
137} 130}
138 131
139static int mbox_fifo_empty(struct omap_mbox *mbox) 132static int mbox_fifo_empty(struct omap_mbox *mbox)
140{ 133{
141 struct omap_mbox_fifo *fifo = 134 struct omap_mbox_fifo *fifo = &mbox->rx_fifo;
142 &((struct omap_mbox_priv *)mbox->priv)->rx_fifo;
143 return (mbox_read_reg(fifo->msg_stat) == 0); 135 return (mbox_read_reg(fifo->msg_stat) == 0);
144} 136}
145 137
146static int mbox_fifo_full(struct omap_mbox *mbox) 138static int mbox_fifo_full(struct omap_mbox *mbox)
147{ 139{
148 struct omap_mbox_fifo *fifo = 140 struct omap_mbox_fifo *fifo = &mbox->tx_fifo;
149 &((struct omap_mbox_priv *)mbox->priv)->tx_fifo;
150 return mbox_read_reg(fifo->fifo_stat); 141 return mbox_read_reg(fifo->fifo_stat);
151} 142}
152 143
153/* Mailbox IRQ handle functions */ 144/* Mailbox IRQ handle functions */
154static void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 145static void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
155{ 146{
156 struct omap_mbox_priv *p = mbox->priv; 147 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
157 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; 148 &mbox->tx_fifo : &mbox->rx_fifo;
149 u32 bit = fifo->intr_bit;
150 u32 irqstatus = fifo->irqstatus;
158 151
159 mbox_write_reg(bit, p->irqstatus); 152 mbox_write_reg(bit, irqstatus);
160 153
161 /* Flush posted write for irq status to avoid spurious interrupts */ 154 /* Flush posted write for irq status to avoid spurious interrupts */
162 mbox_read_reg(p->irqstatus); 155 mbox_read_reg(irqstatus);
163} 156}
164 157
165static int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 158static int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
166{ 159{
167 struct omap_mbox_priv *p = mbox->priv; 160 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
168 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; 161 &mbox->tx_fifo : &mbox->rx_fifo;
169 u32 enable = mbox_read_reg(p->irqenable); 162 u32 bit = fifo->intr_bit;
170 u32 status = mbox_read_reg(p->irqstatus); 163 u32 irqenable = fifo->irqenable;
164 u32 irqstatus = fifo->irqstatus;
165
166 u32 enable = mbox_read_reg(irqenable);
167 u32 status = mbox_read_reg(irqstatus);
171 168
172 return (int)(enable & status & bit); 169 return (int)(enable & status & bit);
173} 170}
@@ -206,18 +203,17 @@ EXPORT_SYMBOL(omap_mbox_msg_send);
206void omap_mbox_save_ctx(struct omap_mbox *mbox) 203void omap_mbox_save_ctx(struct omap_mbox *mbox)
207{ 204{
208 int i; 205 int i;
209 struct omap_mbox_priv *p = mbox->priv;
210 int nr_regs; 206 int nr_regs;
211 207
212 if (p->intr_type) 208 if (mbox->intr_type)
213 nr_regs = OMAP4_MBOX_NR_REGS; 209 nr_regs = OMAP4_MBOX_NR_REGS;
214 else 210 else
215 nr_regs = MBOX_NR_REGS; 211 nr_regs = MBOX_NR_REGS;
216 for (i = 0; i < nr_regs; i++) { 212 for (i = 0; i < nr_regs; i++) {
217 p->ctx[i] = mbox_read_reg(i * sizeof(u32)); 213 mbox->ctx[i] = mbox_read_reg(i * sizeof(u32));
218 214
219 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__, 215 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
220 i, p->ctx[i]); 216 i, mbox->ctx[i]);
221 } 217 }
222} 218}
223EXPORT_SYMBOL(omap_mbox_save_ctx); 219EXPORT_SYMBOL(omap_mbox_save_ctx);
@@ -225,46 +221,50 @@ EXPORT_SYMBOL(omap_mbox_save_ctx);
225void omap_mbox_restore_ctx(struct omap_mbox *mbox) 221void omap_mbox_restore_ctx(struct omap_mbox *mbox)
226{ 222{
227 int i; 223 int i;
228 struct omap_mbox_priv *p = mbox->priv;
229 int nr_regs; 224 int nr_regs;
230 225
231 if (p->intr_type) 226 if (mbox->intr_type)
232 nr_regs = OMAP4_MBOX_NR_REGS; 227 nr_regs = OMAP4_MBOX_NR_REGS;
233 else 228 else
234 nr_regs = MBOX_NR_REGS; 229 nr_regs = MBOX_NR_REGS;
235 for (i = 0; i < nr_regs; i++) { 230 for (i = 0; i < nr_regs; i++) {
236 mbox_write_reg(p->ctx[i], i * sizeof(u32)); 231 mbox_write_reg(mbox->ctx[i], i * sizeof(u32));
237 232
238 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__, 233 dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
239 i, p->ctx[i]); 234 i, mbox->ctx[i]);
240 } 235 }
241} 236}
242EXPORT_SYMBOL(omap_mbox_restore_ctx); 237EXPORT_SYMBOL(omap_mbox_restore_ctx);
243 238
244void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 239void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
245{ 240{
246 struct omap_mbox_priv *p = mbox->priv; 241 u32 l;
247 u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; 242 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
243 &mbox->tx_fifo : &mbox->rx_fifo;
244 u32 bit = fifo->intr_bit;
245 u32 irqenable = fifo->irqenable;
248 246
249 l = mbox_read_reg(p->irqenable); 247 l = mbox_read_reg(irqenable);
250 l |= bit; 248 l |= bit;
251 mbox_write_reg(l, p->irqenable); 249 mbox_write_reg(l, irqenable);
252} 250}
253EXPORT_SYMBOL(omap_mbox_enable_irq); 251EXPORT_SYMBOL(omap_mbox_enable_irq);
254 252
255void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 253void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
256{ 254{
257 struct omap_mbox_priv *p = mbox->priv; 255 struct omap_mbox_fifo *fifo = (irq == IRQ_TX) ?
258 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; 256 &mbox->tx_fifo : &mbox->rx_fifo;
257 u32 bit = fifo->intr_bit;
258 u32 irqdisable = fifo->irqdisable;
259 259
260 /* 260 /*
261 * Read and update the interrupt configuration register for pre-OMAP4. 261 * Read and update the interrupt configuration register for pre-OMAP4.
262 * OMAP4 and later SoCs have a dedicated interrupt disabling register. 262 * OMAP4 and later SoCs have a dedicated interrupt disabling register.
263 */ 263 */
264 if (!p->intr_type) 264 if (!mbox->intr_type)
265 bit = mbox_read_reg(p->irqdisable) & ~bit; 265 bit = mbox_read_reg(irqdisable) & ~bit;
266 266
267 mbox_write_reg(bit, p->irqdisable); 267 mbox_write_reg(bit, irqdisable);
268} 268}
269EXPORT_SYMBOL(omap_mbox_disable_irq); 269EXPORT_SYMBOL(omap_mbox_disable_irq);
270 270
@@ -548,9 +548,9 @@ static int omap_mbox_probe(struct platform_device *pdev)
548 struct resource *mem; 548 struct resource *mem;
549 int ret; 549 int ret;
550 struct omap_mbox **list, *mbox, *mboxblk; 550 struct omap_mbox **list, *mbox, *mboxblk;
551 struct omap_mbox_priv *priv, *privblk;
552 struct omap_mbox_pdata *pdata = pdev->dev.platform_data; 551 struct omap_mbox_pdata *pdata = pdev->dev.platform_data;
553 struct omap_mbox_dev_info *info; 552 struct omap_mbox_dev_info *info;
553 struct omap_mbox_fifo *fifo;
554 u32 intr_type; 554 u32 intr_type;
555 u32 l; 555 u32 l;
556 int i; 556 int i;
@@ -571,28 +571,28 @@ static int omap_mbox_probe(struct platform_device *pdev)
571 if (!mboxblk) 571 if (!mboxblk)
572 return -ENOMEM; 572 return -ENOMEM;
573 573
574 privblk = devm_kzalloc(&pdev->dev, pdata->info_cnt * sizeof(*priv),
575 GFP_KERNEL);
576 if (!privblk)
577 return -ENOMEM;
578
579 info = pdata->info; 574 info = pdata->info;
580 intr_type = pdata->intr_type; 575 intr_type = pdata->intr_type;
581 mbox = mboxblk; 576 mbox = mboxblk;
582 priv = privblk; 577 for (i = 0; i < pdata->info_cnt; i++, info++) {
583 for (i = 0; i < pdata->info_cnt; i++, info++, priv++) { 578 fifo = &mbox->tx_fifo;
584 priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id); 579 fifo->msg = MAILBOX_MESSAGE(info->tx_id);
585 priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id); 580 fifo->fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id);
586 priv->rx_fifo.msg = MAILBOX_MESSAGE(info->rx_id); 581 fifo->intr_bit = MAILBOX_IRQ_NOTFULL(info->tx_id);
587 priv->rx_fifo.msg_stat = MAILBOX_MSGSTATUS(info->rx_id); 582 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id);
588 priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id); 583 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id);
589 priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id); 584 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id);
590 priv->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id); 585
591 priv->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id); 586 fifo = &mbox->rx_fifo;
592 priv->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id); 587 fifo->msg = MAILBOX_MESSAGE(info->rx_id);
593 priv->intr_type = intr_type; 588 fifo->msg_stat = MAILBOX_MSGSTATUS(info->rx_id);
594 589 fifo->intr_bit = MAILBOX_IRQ_NEWMSG(info->rx_id);
595 mbox->priv = priv; 590 fifo->irqenable = MAILBOX_IRQENABLE(intr_type, info->usr_id);
591 fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, info->usr_id);
592 fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, info->usr_id);
593
594 mbox->intr_type = intr_type;
595
596 mbox->name = info->name; 596 mbox->name = info->name;
597 mbox->irq = platform_get_irq(pdev, info->irq_id); 597 mbox->irq = platform_get_irq(pdev, info->irq_id);
598 if (mbox->irq < 0) 598 if (mbox->irq < 0)