diff options
-rw-r--r-- | drivers/mailbox/omap-mailbox.c | 126 |
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 | |||
74 | struct 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 | ||
86 | struct omap_mbox_queue { | 78 | struct 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 */ |
125 | static mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) | 120 | static 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 | ||
132 | static void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) | 126 | static 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 | ||
139 | static int mbox_fifo_empty(struct omap_mbox *mbox) | 132 | static 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 | ||
146 | static int mbox_fifo_full(struct omap_mbox *mbox) | 138 | static 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 */ |
154 | static void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) | 145 | static 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 | ||
165 | static int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) | 158 | static 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); | |||
206 | void omap_mbox_save_ctx(struct omap_mbox *mbox) | 203 | void 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 | } |
223 | EXPORT_SYMBOL(omap_mbox_save_ctx); | 219 | EXPORT_SYMBOL(omap_mbox_save_ctx); |
@@ -225,46 +221,50 @@ EXPORT_SYMBOL(omap_mbox_save_ctx); | |||
225 | void omap_mbox_restore_ctx(struct omap_mbox *mbox) | 221 | void 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 | } |
242 | EXPORT_SYMBOL(omap_mbox_restore_ctx); | 237 | EXPORT_SYMBOL(omap_mbox_restore_ctx); |
243 | 238 | ||
244 | void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) | 239 | void 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 | } |
253 | EXPORT_SYMBOL(omap_mbox_enable_irq); | 251 | EXPORT_SYMBOL(omap_mbox_enable_irq); |
254 | 252 | ||
255 | void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) | 253 | void 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 | } |
269 | EXPORT_SYMBOL(omap_mbox_disable_irq); | 269 | EXPORT_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) |