Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'omap-for-v3.11/mailbox-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/drivers

From Tony Lindgren:

Move OMAP Mailbox framework to drivers via Suman Anna <s-anna@ti.com>

The OMAP Mailbox driver framework is moved out of arch/arm folder
into drivers/mailbox folder, to re-enable building it and also serve
as a baseline for adapting to the new mailbox driver framework. The
changes mainly contain:
- a minor bug fix and cleanup of mach-specific mailbox code
- remove any header dependencies from plat-omap for multi-platform
support
- represent mailbox device data through platform data/hwmod attrs
- move the omap mailbox code out of plat-omap/mach-omapX to
drivers/mailbox folder

* tag 'omap-for-v3.11/mailbox-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
mailbox/omap: move the OMAP mailbox framework to drivers
ARM: OMAP2+: add user and fifo info to mailbox platform data
ARM: OMAP2+: mbox: remove dependencies with soc.h
omap: mailbox: correct the argument type for irq ops
omap: mailbox: call request_irq after mbox queues are allocated
omap: mailbox: check iomem resource before dereferencing it

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+360 -281
+2 -1
arch/arm/configs/omap1_defconfig
··· 26 26 CONFIG_ARCH_OMAP1=y 27 27 CONFIG_OMAP_RESET_CLOCKS=y 28 28 # CONFIG_OMAP_MUX is not set 29 - CONFIG_OMAP_MBOX_FWK=y 29 + CONFIG_MAILBOX=y 30 + CONFIG_OMAP1_MBOX=y 30 31 CONFIG_OMAP_32K_TIMER=y 31 32 CONFIG_OMAP_DM_TIMER=y 32 33 CONFIG_ARCH_OMAP730=y
-4
arch/arm/mach-omap1/Makefile
··· 19 19 # Power Management 20 20 obj-$(CONFIG_PM) += pm.o sleep.o 21 21 22 - # DSP 23 - obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o 24 - mailbox_mach-objs := mailbox.o 25 - 26 22 i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o 27 23 obj-y += $(i2c-omap-m) $(i2c-omap-y) 28 24
+8 -4
arch/arm/mach-omap1/mailbox.c drivers/mailbox/mailbox-omap1.c
··· 13 13 #include <linux/interrupt.h> 14 14 #include <linux/platform_device.h> 15 15 #include <linux/io.h> 16 - #include <plat/mailbox.h> 16 + 17 + #include "omap-mbox.h" 17 18 18 19 #define MAILBOX_ARM2DSP1 0x00 19 20 #define MAILBOX_ARM2DSP1b 0x04 ··· 87 86 88 87 /* irq */ 89 88 static void 90 - omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) 89 + omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 91 90 { 92 91 if (irq == IRQ_RX) 93 92 enable_irq(mbox->irq); 94 93 } 95 94 96 95 static void 97 - omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) 96 + omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 98 97 { 99 98 if (irq == IRQ_RX) 100 99 disable_irq(mbox->irq); 101 100 } 102 101 103 102 static int 104 - omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq) 103 + omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 105 104 { 106 105 if (irq == IRQ_TX) 107 106 return 0; ··· 153 152 list[0]->irq = platform_get_irq_byname(pdev, "dsp"); 154 153 155 154 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 155 + if (!mem) 156 + return -ENOENT; 157 + 156 158 mbox_base = ioremap(mem->start, resource_size(mem)); 157 159 if (!mbox_base) 158 160 return -ENOMEM;
-3
arch/arm/mach-omap2/Makefile
··· 203 203 obj-$(CONFIG_OMAP3_EMU) += emu.o 204 204 obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o 205 205 206 - obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o 207 - mailbox_mach-objs := mailbox.o 208 - 209 206 iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o 210 207 obj-y += $(iommu-m) $(iommu-y) 211 208
+10 -3
arch/arm/mach-omap2/devices.c
··· 20 20 #include <linux/pinctrl/machine.h> 21 21 #include <linux/platform_data/omap4-keypad.h> 22 22 #include <linux/platform_data/omap_ocp2scp.h> 23 + #include <linux/platform_data/mailbox-omap.h> 23 24 #include <linux/usb/omap_control_usb.h> 24 25 25 26 #include <asm/mach-types.h> ··· 328 327 return 0; 329 328 } 330 329 331 - #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) 330 + #if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) 332 331 static inline void __init omap_init_mbox(void) 333 332 { 334 333 struct omap_hwmod *oh; 335 334 struct platform_device *pdev; 335 + struct omap_mbox_pdata *pdata; 336 336 337 337 oh = omap_hwmod_lookup("mailbox"); 338 338 if (!oh) { 339 339 pr_err("%s: unable to find hwmod\n", __func__); 340 340 return; 341 341 } 342 + if (!oh->dev_attr) { 343 + pr_err("%s: hwmod doesn't have valid attrs\n", __func__); 344 + return; 345 + } 342 346 343 - pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0); 347 + pdata = (struct omap_mbox_pdata *)oh->dev_attr; 348 + pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata)); 344 349 WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", 345 350 __func__, PTR_ERR(pdev)); 346 351 } 347 352 #else 348 353 static inline void omap_init_mbox(void) { } 349 - #endif /* CONFIG_OMAP_MBOX_FWK */ 354 + #endif /* CONFIG_OMAP2PLUS_MBOX */ 350 355 351 356 static inline void omap_init_sti(void) {} 352 357
+107 -179
arch/arm/mach-omap2/mailbox.c drivers/mailbox/mailbox-omap2.c
··· 11 11 */ 12 12 13 13 #include <linux/module.h> 14 + #include <linux/slab.h> 14 15 #include <linux/clk.h> 15 16 #include <linux/err.h> 16 17 #include <linux/platform_device.h> 17 18 #include <linux/io.h> 18 19 #include <linux/pm_runtime.h> 20 + #include <linux/platform_data/mailbox-omap.h> 19 21 20 - #include <plat/mailbox.h> 21 - 22 - #include "soc.h" 22 + #include "omap-mbox.h" 23 23 24 24 #define MAILBOX_REVISION 0x000 25 25 #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m)) ··· 59 59 u32 notfull_bit; 60 60 u32 ctx[OMAP4_MBOX_NR_REGS]; 61 61 unsigned long irqdisable; 62 + u32 intr_type; 62 63 }; 63 - 64 - static void omap2_mbox_enable_irq(struct omap_mbox *mbox, 65 - omap_mbox_type_t irq); 66 64 67 65 static inline unsigned int mbox_read_reg(size_t ofs) 68 66 { ··· 122 124 } 123 125 124 126 /* Mailbox IRQ handle functions */ 125 - static void omap2_mbox_enable_irq(struct omap_mbox *mbox, 126 - omap_mbox_type_t irq) 127 + static void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 127 128 { 128 129 struct omap_mbox2_priv *p = mbox->priv; 129 130 u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; ··· 132 135 mbox_write_reg(l, p->irqenable); 133 136 } 134 137 135 - static void omap2_mbox_disable_irq(struct omap_mbox *mbox, 136 - omap_mbox_type_t irq) 138 + static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 137 139 { 138 140 struct omap_mbox2_priv *p = mbox->priv; 139 141 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; 140 142 141 - if (!cpu_is_omap44xx()) 143 + /* 144 + * Read and update the interrupt configuration register for pre-OMAP4. 145 + * OMAP4 and later SoCs have a dedicated interrupt disabling register. 146 + */ 147 + if (!p->intr_type) 142 148 bit = mbox_read_reg(p->irqdisable) & ~bit; 143 149 144 150 mbox_write_reg(bit, p->irqdisable); 145 151 } 146 152 147 - static void omap2_mbox_ack_irq(struct omap_mbox *mbox, 148 - omap_mbox_type_t irq) 153 + static void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 149 154 { 150 155 struct omap_mbox2_priv *p = mbox->priv; 151 156 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; ··· 158 159 mbox_read_reg(p->irqstatus); 159 160 } 160 161 161 - static int omap2_mbox_is_irq(struct omap_mbox *mbox, 162 - omap_mbox_type_t irq) 162 + static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 163 163 { 164 164 struct omap_mbox2_priv *p = mbox->priv; 165 165 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; ··· 173 175 int i; 174 176 struct omap_mbox2_priv *p = mbox->priv; 175 177 int nr_regs; 176 - if (cpu_is_omap44xx()) 178 + 179 + if (p->intr_type) 177 180 nr_regs = OMAP4_MBOX_NR_REGS; 178 181 else 179 182 nr_regs = MBOX_NR_REGS; ··· 191 192 int i; 192 193 struct omap_mbox2_priv *p = mbox->priv; 193 194 int nr_regs; 194 - if (cpu_is_omap44xx()) 195 + 196 + if (p->intr_type) 195 197 nr_regs = OMAP4_MBOX_NR_REGS; 196 198 else 197 199 nr_regs = MBOX_NR_REGS; ··· 220 220 .restore_ctx = omap2_mbox_restore_ctx, 221 221 }; 222 222 223 - /* 224 - * MAILBOX 0: ARM -> DSP, 225 - * MAILBOX 1: ARM <- DSP. 226 - * MAILBOX 2: ARM -> IVA, 227 - * MAILBOX 3: ARM <- IVA. 228 - */ 229 - 230 - /* FIXME: the following structs should be filled automatically by the user id */ 231 - 232 - #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP2) 233 - /* DSP */ 234 - static struct omap_mbox2_priv omap2_mbox_dsp_priv = { 235 - .tx_fifo = { 236 - .msg = MAILBOX_MESSAGE(0), 237 - .fifo_stat = MAILBOX_FIFOSTATUS(0), 238 - }, 239 - .rx_fifo = { 240 - .msg = MAILBOX_MESSAGE(1), 241 - .msg_stat = MAILBOX_MSGSTATUS(1), 242 - }, 243 - .irqenable = MAILBOX_IRQENABLE(0), 244 - .irqstatus = MAILBOX_IRQSTATUS(0), 245 - .notfull_bit = MAILBOX_IRQ_NOTFULL(0), 246 - .newmsg_bit = MAILBOX_IRQ_NEWMSG(1), 247 - .irqdisable = MAILBOX_IRQENABLE(0), 248 - }; 249 - 250 - struct omap_mbox mbox_dsp_info = { 251 - .name = "dsp", 252 - .ops = &omap2_mbox_ops, 253 - .priv = &omap2_mbox_dsp_priv, 254 - }; 255 - #endif 256 - 257 - #if defined(CONFIG_ARCH_OMAP3) 258 - struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL }; 259 - #endif 260 - 261 - #if defined(CONFIG_SOC_OMAP2420) 262 - /* IVA */ 263 - static struct omap_mbox2_priv omap2_mbox_iva_priv = { 264 - .tx_fifo = { 265 - .msg = MAILBOX_MESSAGE(2), 266 - .fifo_stat = MAILBOX_FIFOSTATUS(2), 267 - }, 268 - .rx_fifo = { 269 - .msg = MAILBOX_MESSAGE(3), 270 - .msg_stat = MAILBOX_MSGSTATUS(3), 271 - }, 272 - .irqenable = MAILBOX_IRQENABLE(3), 273 - .irqstatus = MAILBOX_IRQSTATUS(3), 274 - .notfull_bit = MAILBOX_IRQ_NOTFULL(2), 275 - .newmsg_bit = MAILBOX_IRQ_NEWMSG(3), 276 - .irqdisable = MAILBOX_IRQENABLE(3), 277 - }; 278 - 279 - static struct omap_mbox mbox_iva_info = { 280 - .name = "iva", 281 - .ops = &omap2_mbox_ops, 282 - .priv = &omap2_mbox_iva_priv, 283 - }; 284 - #endif 285 - 286 - #ifdef CONFIG_ARCH_OMAP2 287 - struct omap_mbox *omap2_mboxes[] = { 288 - &mbox_dsp_info, 289 - #ifdef CONFIG_SOC_OMAP2420 290 - &mbox_iva_info, 291 - #endif 292 - NULL 293 - }; 294 - #endif 295 - 296 - #if defined(CONFIG_ARCH_OMAP4) 297 - /* OMAP4 */ 298 - static struct omap_mbox2_priv omap2_mbox_1_priv = { 299 - .tx_fifo = { 300 - .msg = MAILBOX_MESSAGE(0), 301 - .fifo_stat = MAILBOX_FIFOSTATUS(0), 302 - }, 303 - .rx_fifo = { 304 - .msg = MAILBOX_MESSAGE(1), 305 - .msg_stat = MAILBOX_MSGSTATUS(1), 306 - }, 307 - .irqenable = OMAP4_MAILBOX_IRQENABLE(0), 308 - .irqstatus = OMAP4_MAILBOX_IRQSTATUS(0), 309 - .notfull_bit = MAILBOX_IRQ_NOTFULL(0), 310 - .newmsg_bit = MAILBOX_IRQ_NEWMSG(1), 311 - .irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0), 312 - }; 313 - 314 - struct omap_mbox mbox_1_info = { 315 - .name = "mailbox-1", 316 - .ops = &omap2_mbox_ops, 317 - .priv = &omap2_mbox_1_priv, 318 - }; 319 - 320 - static struct omap_mbox2_priv omap2_mbox_2_priv = { 321 - .tx_fifo = { 322 - .msg = MAILBOX_MESSAGE(3), 323 - .fifo_stat = MAILBOX_FIFOSTATUS(3), 324 - }, 325 - .rx_fifo = { 326 - .msg = MAILBOX_MESSAGE(2), 327 - .msg_stat = MAILBOX_MSGSTATUS(2), 328 - }, 329 - .irqenable = OMAP4_MAILBOX_IRQENABLE(0), 330 - .irqstatus = OMAP4_MAILBOX_IRQSTATUS(0), 331 - .notfull_bit = MAILBOX_IRQ_NOTFULL(3), 332 - .newmsg_bit = MAILBOX_IRQ_NEWMSG(2), 333 - .irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0), 334 - }; 335 - 336 - struct omap_mbox mbox_2_info = { 337 - .name = "mailbox-2", 338 - .ops = &omap2_mbox_ops, 339 - .priv = &omap2_mbox_2_priv, 340 - }; 341 - 342 - struct omap_mbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL }; 343 - #endif 344 - 345 223 static int omap2_mbox_probe(struct platform_device *pdev) 346 224 { 347 225 struct resource *mem; 348 226 int ret; 349 - struct omap_mbox **list; 227 + struct omap_mbox **list, *mbox, *mboxblk; 228 + struct omap_mbox2_priv *priv, *privblk; 229 + struct omap_mbox_pdata *pdata = pdev->dev.platform_data; 230 + struct omap_mbox_dev_info *info; 231 + int i; 350 232 351 - if (false) 352 - ; 353 - #if defined(CONFIG_ARCH_OMAP3) 354 - else if (cpu_is_omap34xx()) { 355 - list = omap3_mboxes; 356 - 357 - list[0]->irq = platform_get_irq(pdev, 0); 358 - } 359 - #endif 360 - #if defined(CONFIG_ARCH_OMAP2) 361 - else if (cpu_is_omap2430()) { 362 - list = omap2_mboxes; 363 - 364 - list[0]->irq = platform_get_irq(pdev, 0); 365 - } else if (cpu_is_omap2420()) { 366 - list = omap2_mboxes; 367 - 368 - list[0]->irq = platform_get_irq_byname(pdev, "dsp"); 369 - list[1]->irq = platform_get_irq_byname(pdev, "iva"); 370 - } 371 - #endif 372 - #if defined(CONFIG_ARCH_OMAP4) 373 - else if (cpu_is_omap44xx()) { 374 - list = omap4_mboxes; 375 - 376 - list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0); 377 - } 378 - #endif 379 - else { 233 + if (!pdata || !pdata->info_cnt || !pdata->info) { 380 234 pr_err("%s: platform not supported\n", __func__); 381 235 return -ENODEV; 382 236 } 383 237 384 - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 385 - mbox_base = ioremap(mem->start, resource_size(mem)); 386 - if (!mbox_base) 238 + /* allocate one extra for marking end of list */ 239 + list = kzalloc((pdata->info_cnt + 1) * sizeof(*list), GFP_KERNEL); 240 + if (!list) 387 241 return -ENOMEM; 388 242 389 - ret = omap_mbox_register(&pdev->dev, list); 390 - if (ret) { 391 - iounmap(mbox_base); 392 - return ret; 243 + mboxblk = mbox = kzalloc(pdata->info_cnt * sizeof(*mbox), GFP_KERNEL); 244 + if (!mboxblk) { 245 + ret = -ENOMEM; 246 + goto free_list; 393 247 } 394 248 249 + privblk = priv = kzalloc(pdata->info_cnt * sizeof(*priv), GFP_KERNEL); 250 + if (!privblk) { 251 + ret = -ENOMEM; 252 + goto free_mboxblk; 253 + } 254 + 255 + info = pdata->info; 256 + for (i = 0; i < pdata->info_cnt; i++, info++, priv++) { 257 + priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id); 258 + priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id); 259 + priv->rx_fifo.msg = MAILBOX_MESSAGE(info->rx_id); 260 + priv->rx_fifo.msg_stat = MAILBOX_MSGSTATUS(info->rx_id); 261 + priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id); 262 + priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id); 263 + if (pdata->intr_type) { 264 + priv->irqenable = OMAP4_MAILBOX_IRQENABLE(info->usr_id); 265 + priv->irqstatus = OMAP4_MAILBOX_IRQSTATUS(info->usr_id); 266 + priv->irqdisable = 267 + OMAP4_MAILBOX_IRQENABLE_CLR(info->usr_id); 268 + } else { 269 + priv->irqenable = MAILBOX_IRQENABLE(info->usr_id); 270 + priv->irqstatus = MAILBOX_IRQSTATUS(info->usr_id); 271 + priv->irqdisable = MAILBOX_IRQENABLE(info->usr_id); 272 + } 273 + priv->intr_type = pdata->intr_type; 274 + 275 + mbox->priv = priv; 276 + mbox->name = info->name; 277 + mbox->ops = &omap2_mbox_ops; 278 + mbox->irq = platform_get_irq(pdev, info->irq_id); 279 + if (mbox->irq < 0) { 280 + ret = mbox->irq; 281 + goto free_privblk; 282 + } 283 + list[i] = mbox++; 284 + } 285 + 286 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 287 + if (!mem) { 288 + ret = -ENOENT; 289 + goto free_privblk; 290 + } 291 + 292 + mbox_base = ioremap(mem->start, resource_size(mem)); 293 + if (!mbox_base) { 294 + ret = -ENOMEM; 295 + goto free_privblk; 296 + } 297 + 298 + ret = omap_mbox_register(&pdev->dev, list); 299 + if (ret) 300 + goto unmap_mbox; 301 + platform_set_drvdata(pdev, list); 302 + 395 303 return 0; 304 + 305 + unmap_mbox: 306 + iounmap(mbox_base); 307 + free_privblk: 308 + kfree(privblk); 309 + free_mboxblk: 310 + kfree(mboxblk); 311 + free_list: 312 + kfree(list); 313 + return ret; 396 314 } 397 315 398 316 static int omap2_mbox_remove(struct platform_device *pdev) 399 317 { 318 + struct omap_mbox2_priv *privblk; 319 + struct omap_mbox **list = platform_get_drvdata(pdev); 320 + struct omap_mbox *mboxblk = list[0]; 321 + 322 + privblk = mboxblk->priv; 400 323 omap_mbox_unregister(); 401 324 iounmap(mbox_base); 325 + kfree(privblk); 326 + kfree(mboxblk); 327 + kfree(list); 328 + platform_set_drvdata(pdev, NULL); 329 + 402 330 return 0; 403 331 } 404 332 405 333 static struct platform_driver omap2_mbox_driver = { 406 - .probe = omap2_mbox_probe, 407 - .remove = omap2_mbox_remove, 408 - .driver = { 334 + .probe = omap2_mbox_probe, 335 + .remove = omap2_mbox_remove, 336 + .driver = { 409 337 .name = "omap-mailbox", 410 338 }, 411 339 };
+14
arch/arm/mach-omap2/omap_hwmod_2420_data.c
··· 16 16 #include <linux/i2c-omap.h> 17 17 #include <linux/platform_data/spi-omap2-mcspi.h> 18 18 #include <linux/omap-dma.h> 19 + #include <linux/platform_data/mailbox-omap.h> 19 20 #include <plat/dmtimer.h> 20 21 21 22 #include "omap_hwmod.h" ··· 167 166 }; 168 167 169 168 /* mailbox */ 169 + static struct omap_mbox_dev_info omap2420_mailbox_info[] = { 170 + { .name = "dsp", .tx_id = 0, .rx_id = 1, .irq_id = 0, .usr_id = 0 }, 171 + { .name = "iva", .tx_id = 2, .rx_id = 3, .irq_id = 1, .usr_id = 3 }, 172 + }; 173 + 174 + static struct omap_mbox_pdata omap2420_mailbox_attrs = { 175 + .num_users = 4, 176 + .num_fifos = 6, 177 + .info_cnt = ARRAY_SIZE(omap2420_mailbox_info), 178 + .info = omap2420_mailbox_info, 179 + }; 180 + 170 181 static struct omap_hwmod_irq_info omap2420_mailbox_irqs[] = { 171 182 { .name = "dsp", .irq = 26 + OMAP_INTC_START, }, 172 183 { .name = "iva", .irq = 34 + OMAP_INTC_START, }, ··· 199 186 .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT, 200 187 }, 201 188 }, 189 + .dev_attr = &omap2420_mailbox_attrs, 202 190 }; 203 191 204 192 /*
+13
arch/arm/mach-omap2/omap_hwmod_2430_data.c
··· 17 17 #include <linux/platform_data/asoc-ti-mcbsp.h> 18 18 #include <linux/platform_data/spi-omap2-mcspi.h> 19 19 #include <linux/omap-dma.h> 20 + #include <linux/platform_data/mailbox-omap.h> 20 21 #include <plat/dmtimer.h> 21 22 22 23 #include "omap_hwmod.h" ··· 171 170 }; 172 171 173 172 /* mailbox */ 173 + static struct omap_mbox_dev_info omap2430_mailbox_info[] = { 174 + { .name = "dsp", .tx_id = 0, .rx_id = 1 }, 175 + }; 176 + 177 + static struct omap_mbox_pdata omap2430_mailbox_attrs = { 178 + .num_users = 4, 179 + .num_fifos = 6, 180 + .info_cnt = ARRAY_SIZE(omap2430_mailbox_info), 181 + .info = omap2430_mailbox_info, 182 + }; 183 + 174 184 static struct omap_hwmod_irq_info omap2430_mailbox_irqs[] = { 175 185 { .irq = 26 + OMAP_INTC_START, }, 176 186 { .irq = -1 }, ··· 201 189 .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT, 202 190 }, 203 191 }, 192 + .dev_attr = &omap2430_mailbox_attrs, 204 193 }; 205 194 206 195 /* mcspi3 */
+13
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
··· 25 25 #include <linux/platform_data/asoc-ti-mcbsp.h> 26 26 #include <linux/platform_data/spi-omap2-mcspi.h> 27 27 #include <linux/platform_data/iommu-omap.h> 28 + #include <linux/platform_data/mailbox-omap.h> 28 29 #include <plat/dmtimer.h> 29 30 30 31 #include "am35xx.h" ··· 1506 1505 .sysc = &omap3xxx_mailbox_sysc, 1507 1506 }; 1508 1507 1508 + static struct omap_mbox_dev_info omap3xxx_mailbox_info[] = { 1509 + { .name = "dsp", .tx_id = 0, .rx_id = 1 }, 1510 + }; 1511 + 1512 + static struct omap_mbox_pdata omap3xxx_mailbox_attrs = { 1513 + .num_users = 2, 1514 + .num_fifos = 2, 1515 + .info_cnt = ARRAY_SIZE(omap3xxx_mailbox_info), 1516 + .info = omap3xxx_mailbox_info, 1517 + }; 1518 + 1509 1519 static struct omap_hwmod_irq_info omap3xxx_mailbox_irqs[] = { 1510 1520 { .irq = 26 + OMAP_INTC_START, }, 1511 1521 { .irq = -1 }, ··· 1536 1524 .idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT, 1537 1525 }, 1538 1526 }, 1527 + .dev_attr = &omap3xxx_mailbox_attrs, 1539 1528 }; 1540 1529 1541 1530 /*
-16
arch/arm/plat-omap/Kconfig
··· 86 86 to change the pin multiplexing setup. When there are no warnings 87 87 printed, it's safe to deselect OMAP_MUX for your product. 88 88 89 - config OMAP_MBOX_FWK 90 - tristate "Mailbox framework support" 91 - depends on ARCH_OMAP && !ARCH_MULTIPLATFORM 92 - help 93 - Say Y here if you want to use OMAP Mailbox framework support for 94 - DSP, IVA1.0 and IVA2 in OMAP1/2/3. 95 - 96 - config OMAP_MBOX_KFIFO_SIZE 97 - int "Mailbox kfifo default buffer size (bytes)" 98 - depends on OMAP_MBOX_FWK 99 - default 256 100 - help 101 - Specify the default size of mailbox's kfifo buffers (bytes). 102 - This can also be changed at runtime (via the mbox_kfifo_size 103 - module parameter). 104 - 105 89 config OMAP_IOMMU_IVA2 106 90 bool 107 91
-3
arch/arm/plat-omap/Makefile
··· 17 17 i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o 18 18 obj-y += $(i2c-omap-m) $(i2c-omap-y) 19 19 20 - # OMAP mailbox framework 21 - obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o 22 -
+16 -54
arch/arm/plat-omap/include/plat/mailbox.h drivers/mailbox/omap-mbox.h
··· 1 - /* mailbox.h */ 1 + /* 2 + * omap-mbox.h: OMAP mailbox internal definitions 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 2 8 3 - #ifndef MAILBOX_H 4 - #define MAILBOX_H 9 + #ifndef OMAP_MBOX_H 10 + #define OMAP_MBOX_H 5 11 12 + #include <linux/device.h> 13 + #include <linux/interrupt.h> 14 + #include <linux/kfifo.h> 6 15 #include <linux/spinlock.h> 7 16 #include <linux/workqueue.h> 8 - #include <linux/interrupt.h> 9 - #include <linux/device.h> 10 - #include <linux/kfifo.h> 11 - 12 - typedef u32 mbox_msg_t; 13 - struct omap_mbox; 14 - 15 - typedef int __bitwise omap_mbox_irq_t; 16 - #define IRQ_TX ((__force omap_mbox_irq_t) 1) 17 - #define IRQ_RX ((__force omap_mbox_irq_t) 2) 17 + #include <linux/omap-mailbox.h> 18 18 19 19 typedef int __bitwise omap_mbox_type_t; 20 20 #define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1) ··· 51 51 }; 52 52 53 53 struct omap_mbox { 54 - char *name; 54 + const char *name; 55 55 unsigned int irq; 56 56 struct omap_mbox_queue *txq, *rxq; 57 57 struct omap_mbox_ops *ops; 58 58 struct device *dev; 59 59 void *priv; 60 60 int use_count; 61 - struct blocking_notifier_head notifier; 61 + struct blocking_notifier_head notifier; 62 62 }; 63 - 64 - int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); 65 - void omap_mbox_init_seq(struct omap_mbox *); 66 - 67 - struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); 68 - void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); 69 63 70 64 int omap_mbox_register(struct device *parent, struct omap_mbox **); 71 65 int omap_mbox_unregister(void); 72 66 73 - static inline void omap_mbox_save_ctx(struct omap_mbox *mbox) 74 - { 75 - if (!mbox->ops->save_ctx) { 76 - dev_err(mbox->dev, "%s:\tno save\n", __func__); 77 - return; 78 - } 79 - 80 - mbox->ops->save_ctx(mbox); 81 - } 82 - 83 - static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox) 84 - { 85 - if (!mbox->ops->restore_ctx) { 86 - dev_err(mbox->dev, "%s:\tno restore\n", __func__); 87 - return; 88 - } 89 - 90 - mbox->ops->restore_ctx(mbox); 91 - } 92 - 93 - static inline void omap_mbox_enable_irq(struct omap_mbox *mbox, 94 - omap_mbox_irq_t irq) 95 - { 96 - mbox->ops->enable_irq(mbox, irq); 97 - } 98 - 99 - static inline void omap_mbox_disable_irq(struct omap_mbox *mbox, 100 - omap_mbox_irq_t irq) 101 - { 102 - mbox->ops->disable_irq(mbox, irq); 103 - } 104 - 105 - #endif /* MAILBOX_H */ 67 + #endif /* OMAP_MBOX_H */
+44 -10
arch/arm/plat-omap/mailbox.c drivers/mailbox/omap-mailbox.c
··· 31 31 #include <linux/notifier.h> 32 32 #include <linux/module.h> 33 33 34 - #include <plat/mailbox.h> 34 + #include "omap-mbox.h" 35 35 36 36 static struct omap_mbox **mboxes; 37 37 ··· 115 115 return ret; 116 116 } 117 117 EXPORT_SYMBOL(omap_mbox_msg_send); 118 + 119 + void omap_mbox_save_ctx(struct omap_mbox *mbox) 120 + { 121 + if (!mbox->ops->save_ctx) { 122 + dev_err(mbox->dev, "%s:\tno save\n", __func__); 123 + return; 124 + } 125 + 126 + mbox->ops->save_ctx(mbox); 127 + } 128 + EXPORT_SYMBOL(omap_mbox_save_ctx); 129 + 130 + void omap_mbox_restore_ctx(struct omap_mbox *mbox) 131 + { 132 + if (!mbox->ops->restore_ctx) { 133 + dev_err(mbox->dev, "%s:\tno restore\n", __func__); 134 + return; 135 + } 136 + 137 + mbox->ops->restore_ctx(mbox); 138 + } 139 + EXPORT_SYMBOL(omap_mbox_restore_ctx); 140 + 141 + void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 142 + { 143 + mbox->ops->enable_irq(mbox, irq); 144 + } 145 + EXPORT_SYMBOL(omap_mbox_enable_irq); 146 + 147 + void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) 148 + { 149 + mbox->ops->disable_irq(mbox, irq); 150 + } 151 + EXPORT_SYMBOL(omap_mbox_disable_irq); 118 152 119 153 static void mbox_tx_tasklet(unsigned long tx_data) 120 154 { ··· 295 261 } 296 262 297 263 if (!mbox->use_count++) { 298 - ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED, 299 - mbox->name, mbox); 300 - if (unlikely(ret)) { 301 - pr_err("failed to register mailbox interrupt:%d\n", 302 - ret); 303 - goto fail_request_irq; 304 - } 305 264 mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); 306 265 if (!mq) { 307 266 ret = -ENOMEM; ··· 309 282 } 310 283 mbox->rxq = mq; 311 284 mq->mbox = mbox; 285 + ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED, 286 + mbox->name, mbox); 287 + if (unlikely(ret)) { 288 + pr_err("failed to register mailbox interrupt:%d\n", 289 + ret); 290 + goto fail_request_irq; 291 + } 312 292 313 293 omap_mbox_enable_irq(mbox, IRQ_RX); 314 294 } 315 295 mutex_unlock(&mbox_configured_lock); 316 296 return 0; 317 297 298 + fail_request_irq: 299 + mbox_queue_free(mbox->rxq); 318 300 fail_alloc_rxq: 319 301 mbox_queue_free(mbox->txq); 320 302 fail_alloc_txq: 321 - free_irq(mbox->irq, mbox); 322 - fail_request_irq: 323 303 if (mbox->ops->shutdown) 324 304 mbox->ops->shutdown(mbox); 325 305 mbox->use_count--;
+34
drivers/mailbox/Kconfig
··· 16 16 Management Engine, primarily for cpufreq. Say Y here if you want 17 17 to use the PL320 IPCM support. 18 18 19 + config OMAP_MBOX 20 + tristate 21 + help 22 + This option is selected by any OMAP architecture specific mailbox 23 + driver such as CONFIG_OMAP1_MBOX or CONFIG_OMAP2PLUS_MBOX. This 24 + enables the common OMAP mailbox framework code. 25 + 26 + config OMAP1_MBOX 27 + tristate "OMAP1 Mailbox framework support" 28 + depends on ARCH_OMAP1 29 + select OMAP_MBOX 30 + help 31 + Mailbox implementation for OMAP chips with hardware for 32 + interprocessor communication involving DSP in OMAP1. Say Y here 33 + if you want to use OMAP1 Mailbox framework support. 34 + 35 + config OMAP2PLUS_MBOX 36 + tristate "OMAP2+ Mailbox framework support" 37 + depends on ARCH_OMAP2PLUS 38 + select OMAP_MBOX 39 + help 40 + Mailbox implementation for OMAP family chips with hardware for 41 + interprocessor communication involving DSP, IVA1.0 and IVA2 in 42 + OMAP2/3; or IPU, IVA HD and DSP in OMAP4/5. Say Y here if you 43 + want to use OMAP2+ Mailbox framework support. 44 + 45 + config OMAP_MBOX_KFIFO_SIZE 46 + int "Mailbox kfifo default buffer size (bytes)" 47 + depends on OMAP2PLUS_MBOX || OMAP1_MBOX 48 + default 256 49 + help 50 + Specify the default size of mailbox's kfifo buffers (bytes). 51 + This can also be changed at runtime (via the mbox_kfifo_size 52 + module parameter). 19 53 endif
+6
drivers/mailbox/Makefile
··· 1 1 obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o 2 + 3 + obj-$(CONFIG_OMAP_MBOX) += omap-mailbox.o 4 + obj-$(CONFIG_OMAP1_MBOX) += mailbox_omap1.o 5 + mailbox_omap1-objs := mailbox-omap1.o 6 + obj-$(CONFIG_OMAP2PLUS_MBOX) += mailbox_omap2.o 7 + mailbox_omap2-objs := mailbox-omap2.o
+2 -1
drivers/remoteproc/Kconfig
··· 14 14 depends on HAS_DMA 15 15 depends on ARCH_OMAP4 || SOC_OMAP5 16 16 depends on OMAP_IOMMU 17 - depends on OMAP_MBOX_FWK 18 17 select REMOTEPROC 18 + select MAILBOX 19 + select OMAP2PLUS_MBOX 19 20 select RPMSG 20 21 help 21 22 Say y here to support OMAP's remote processors (dual M3
+1 -1
drivers/remoteproc/omap_remoteproc.c
··· 27 27 #include <linux/platform_device.h> 28 28 #include <linux/dma-mapping.h> 29 29 #include <linux/remoteproc.h> 30 + #include <linux/omap-mailbox.h> 30 31 31 - #include <plat/mailbox.h> 32 32 #include <linux/platform_data/remoteproc-omap.h> 33 33 34 34 #include "omap_remoteproc.h"
+2 -1
drivers/staging/tidspbridge/Kconfig
··· 5 5 menuconfig TIDSPBRIDGE 6 6 tristate "DSP Bridge driver" 7 7 depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM 8 - select OMAP_MBOX_FWK 8 + select MAILBOX 9 + select OMAP2PLUS_MBOX 9 10 help 10 11 DSP/BIOS Bridge is designed for platforms that contain a GPP and 11 12 one or more attached DSPs. The GPP is considered the master or
+1 -1
drivers/staging/tidspbridge/include/dspbridge/host_os.h
··· 41 41 #include <linux/ioport.h> 42 42 #include <linux/platform_device.h> 43 43 #include <linux/clk.h> 44 - #include <plat/mailbox.h> 44 + #include <linux/omap-mailbox.h> 45 45 #include <linux/pagemap.h> 46 46 #include <asm/cacheflush.h> 47 47 #include <linux/dma-mapping.h>
+29
include/linux/omap-mailbox.h
··· 1 + /* 2 + * omap-mailbox: interprocessor communication module for OMAP 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef OMAP_MAILBOX_H 10 + #define OMAP_MAILBOX_H 11 + 12 + typedef u32 mbox_msg_t; 13 + struct omap_mbox; 14 + 15 + typedef int __bitwise omap_mbox_irq_t; 16 + #define IRQ_TX ((__force omap_mbox_irq_t) 1) 17 + #define IRQ_RX ((__force omap_mbox_irq_t) 2) 18 + 19 + int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); 20 + 21 + struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); 22 + void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); 23 + 24 + void omap_mbox_save_ctx(struct omap_mbox *mbox); 25 + void omap_mbox_restore_ctx(struct omap_mbox *mbox); 26 + void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq); 27 + void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq); 28 + 29 + #endif /* OMAP_MAILBOX_H */
+58
include/linux/platform_data/mailbox-omap.h
··· 1 + /* 2 + * mailbox-omap.h 3 + * 4 + * Copyright (C) 2013 Texas Instruments, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * version 2 as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #ifndef _PLAT_MAILBOX_H 17 + #define _PLAT_MAILBOX_H 18 + 19 + /* Interrupt register configuration types */ 20 + #define MBOX_INTR_CFG_TYPE1 (0) 21 + #define MBOX_INTR_CFG_TYPE2 (1) 22 + 23 + /** 24 + * struct omap_mbox_dev_info - OMAP mailbox device attribute info 25 + * @name: name of the mailbox device 26 + * @tx_id: mailbox queue id used for transmitting messages 27 + * @rx_id: mailbox queue id on which messages are received 28 + * @irq_id: irq identifier number to use from the hwmod data 29 + * @usr_id: mailbox user id for identifying the interrupt into 30 + * the MPU interrupt controller. 31 + */ 32 + struct omap_mbox_dev_info { 33 + const char *name; 34 + u32 tx_id; 35 + u32 rx_id; 36 + u32 irq_id; 37 + u32 usr_id; 38 + }; 39 + 40 + /** 41 + * struct omap_mbox_pdata - OMAP mailbox platform data 42 + * @intr_type: type of interrupt configuration registers used 43 + while programming mailbox queue interrupts 44 + * @num_users: number of users (processor devices) that the mailbox 45 + * h/w block can interrupt 46 + * @num_fifos: number of h/w fifos within the mailbox h/w block 47 + * @info_cnt: number of mailbox devices for the platform 48 + * @info: array of mailbox device attributes 49 + */ 50 + struct omap_mbox_pdata { 51 + u32 intr_type; 52 + u32 num_users; 53 + u32 num_fifos; 54 + u32 info_cnt; 55 + struct omap_mbox_dev_info *info; 56 + }; 57 + 58 + #endif /* _PLAT_MAILBOX_H */