1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved 4 * Authors: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics. 5 * Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics. 6 */ 7 8 #include <linux/arm-smccc.h> 9 #include <linux/dma-mapping.h> 10 #include <linux/interrupt.h> 11 #include <linux/io.h> 12 #include <linux/mailbox_client.h> 13 #include <linux/mfd/syscon.h> 14 #include <linux/module.h> 15 #include <linux/of_address.h> 16 #include <linux/of_device.h> 17 #include <linux/of_reserved_mem.h> 18 #include <linux/pm_wakeirq.h> 19 #include <linux/regmap.h> 20 #include <linux/remoteproc.h> 21 #include <linux/reset.h> 22 #include <linux/slab.h> 23 #include <linux/workqueue.h> 24 25 #include "remoteproc_internal.h" 26 27 #define HOLD_BOOT 0 28 #define RELEASE_BOOT 1 29 30 #define MBOX_NB_VQ 2 31 #define MBOX_NB_MBX 3 32 33 #define STM32_SMC_RCC 0x82001000 34 #define STM32_SMC_REG_WRITE 0x1 35 36 #define STM32_MBX_VQ0 "vq0" 37 #define STM32_MBX_VQ0_ID 0 38 #define STM32_MBX_VQ1 "vq1" 39 #define STM32_MBX_VQ1_ID 1 40 #define STM32_MBX_SHUTDOWN "shutdown" 41 42 struct stm32_syscon { 43 struct regmap *map; 44 u32 reg; 45 u32 mask; 46 }; 47 48 struct stm32_rproc_mem { 49 char name[20]; 50 void __iomem *cpu_addr; 51 phys_addr_t bus_addr; 52 u32 dev_addr; 53 size_t size; 54 }; 55 56 struct stm32_rproc_mem_ranges { 57 u32 dev_addr; 58 u32 bus_addr; 59 u32 size; 60 }; 61 62 struct stm32_mbox { 63 const unsigned char name[10]; 64 struct mbox_chan *chan; 65 struct mbox_client client; 66 struct work_struct vq_work; 67 int vq_id; 68 }; 69 70 struct stm32_rproc { 71 struct reset_control *rst; 72 struct stm32_syscon hold_boot; 73 struct stm32_syscon pdds; 74 int wdg_irq; 75 u32 nb_rmems; 76 struct stm32_rproc_mem *rmems; 77 struct stm32_mbox mb[MBOX_NB_MBX]; 78 struct workqueue_struct *workqueue; 79 bool secured_soc; 80 }; 81 82 static int stm32_rproc_pa_to_da(struct rproc *rproc, phys_addr_t pa, u64 *da) 83 { 84 unsigned int i; 85 struct stm32_rproc *ddata = rproc->priv; 86 struct stm32_rproc_mem *p_mem; 87 88 for (i = 0; i < ddata->nb_rmems; i++) { 89 p_mem = &ddata->rmems[i]; 90 91 if (pa < p_mem->bus_addr || 92 pa >= p_mem->bus_addr + p_mem->size) 93 continue; 94 *da = pa - p_mem->bus_addr + p_mem->dev_addr; 95 dev_dbg(rproc->dev.parent, "pa %pa to da %llx\n", &pa, *da); 96 return 0; 97 } 98 99 return -EINVAL; 100 } 101 102 static int stm32_rproc_mem_alloc(struct rproc *rproc, 103 struct rproc_mem_entry *mem) 104 { 105 struct device *dev = rproc->dev.parent; 106 void *va; 107 108 dev_dbg(dev, "map memory: %pa+%x\n", &mem->dma, mem->len); 109 va = ioremap_wc(mem->dma, mem->len); 110 if (IS_ERR_OR_NULL(va)) { 111 dev_err(dev, "Unable to map memory region: %pa+%x\n", 112 &mem->dma, mem->len); 113 return -ENOMEM; 114 } 115 116 /* Update memory entry va */ 117 mem->va = va; 118 119 return 0; 120 } 121 122 static int stm32_rproc_mem_release(struct rproc *rproc, 123 struct rproc_mem_entry *mem) 124 { 125 dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma); 126 iounmap(mem->va); 127 128 return 0; 129 } 130 131 static int stm32_rproc_of_memory_translations(struct rproc *rproc) 132 { 133 struct device *parent, *dev = rproc->dev.parent; 134 struct stm32_rproc *ddata = rproc->priv; 135 struct device_node *np; 136 struct stm32_rproc_mem *p_mems; 137 struct stm32_rproc_mem_ranges *mem_range; 138 int cnt, array_size, i, ret = 0; 139 140 parent = dev->parent; 141 np = parent->of_node; 142 143 cnt = of_property_count_elems_of_size(np, "dma-ranges", 144 sizeof(*mem_range)); 145 if (cnt <= 0) { 146 dev_err(dev, "%s: dma-ranges property not defined\n", __func__); 147 return -EINVAL; 148 } 149 150 p_mems = devm_kcalloc(dev, cnt, sizeof(*p_mems), GFP_KERNEL); 151 if (!p_mems) 152 return -ENOMEM; 153 mem_range = kcalloc(cnt, sizeof(*mem_range), GFP_KERNEL); 154 if (!mem_range) 155 return -ENOMEM; 156 157 array_size = cnt * sizeof(struct stm32_rproc_mem_ranges) / sizeof(u32); 158 159 ret = of_property_read_u32_array(np, "dma-ranges", 160 (u32 *)mem_range, array_size); 161 if (ret) { 162 dev_err(dev, "error while get dma-ranges property: %x\n", ret); 163 goto free_mem; 164 } 165 166 for (i = 0; i < cnt; i++) { 167 p_mems[i].bus_addr = mem_range[i].bus_addr; 168 p_mems[i].dev_addr = mem_range[i].dev_addr; 169 p_mems[i].size = mem_range[i].size; 170 171 dev_dbg(dev, "memory range[%i]: da %#x, pa %pa, size %#zx:\n", 172 i, p_mems[i].dev_addr, &p_mems[i].bus_addr, 173 p_mems[i].size); 174 } 175 176 ddata->rmems = p_mems; 177 ddata->nb_rmems = cnt; 178 179 free_mem: 180 kfree(mem_range); 181 return ret; 182 } 183 184 static int stm32_rproc_mbox_idx(struct rproc *rproc, const unsigned char *name) 185 { 186 struct stm32_rproc *ddata = rproc->priv; 187 int i; 188 189 for (i = 0; i < ARRAY_SIZE(ddata->mb); i++) { 190 if (!strncmp(ddata->mb[i].name, name, strlen(name))) 191 return i; 192 } 193 dev_err(&rproc->dev, "mailbox %s not found\n", name); 194 195 return -EINVAL; 196 } 197 198 static int stm32_rproc_elf_load_rsc_table(struct rproc *rproc, 199 const struct firmware *fw) 200 { 201 if (rproc_elf_load_rsc_table(rproc, fw)) 202 dev_warn(&rproc->dev, "no resource table found for this firmware\n"); 203 204 return 0; 205 } 206 207 static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) 208 { 209 struct device *dev = rproc->dev.parent; 210 struct device_node *np = dev->of_node; 211 struct of_phandle_iterator it; 212 struct rproc_mem_entry *mem; 213 struct reserved_mem *rmem; 214 u64 da; 215 int index = 0; 216 217 /* Register associated reserved memory regions */ 218 of_phandle_iterator_init(&it, np, "memory-region", NULL, 0); 219 while (of_phandle_iterator_next(&it) == 0) { 220 rmem = of_reserved_mem_lookup(it.node); 221 if (!rmem) { 222 dev_err(dev, "unable to acquire memory-region\n"); 223 return -EINVAL; 224 } 225 226 if (stm32_rproc_pa_to_da(rproc, rmem->base, &da) < 0) { 227 dev_err(dev, "memory region not valid %pa\n", 228 &rmem->base); 229 return -EINVAL; 230 } 231 232 /* No need to map vdev buffer */ 233 if (strcmp(it.node->name, "vdev0buffer")) { 234 /* Register memory region */ 235 mem = rproc_mem_entry_init(dev, NULL, 236 (dma_addr_t)rmem->base, 237 rmem->size, da, 238 stm32_rproc_mem_alloc, 239 stm32_rproc_mem_release, 240 it.node->name); 241 242 if (mem) 243 rproc_coredump_add_segment(rproc, da, 244 rmem->size); 245 } else { 246 /* Register reserved memory for vdev buffer alloc */ 247 mem = rproc_of_resm_mem_entry_init(dev, index, 248 rmem->size, 249 rmem->base, 250 it.node->name); 251 } 252 253 if (!mem) 254 return -ENOMEM; 255 256 rproc_add_carveout(rproc, mem); 257 index++; 258 } 259 260 return stm32_rproc_elf_load_rsc_table(rproc, fw); 261 } 262 263 static irqreturn_t stm32_rproc_wdg(int irq, void *data) 264 { 265 struct rproc *rproc = data; 266 267 rproc_report_crash(rproc, RPROC_WATCHDOG); 268 269 return IRQ_HANDLED; 270 } 271 272 static void stm32_rproc_mb_vq_work(struct work_struct *work) 273 { 274 struct stm32_mbox *mb = container_of(work, struct stm32_mbox, vq_work); 275 struct rproc *rproc = dev_get_drvdata(mb->client.dev); 276 277 if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) 278 dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id); 279 } 280 281 static void stm32_rproc_mb_callback(struct mbox_client *cl, void *data) 282 { 283 struct rproc *rproc = dev_get_drvdata(cl->dev); 284 struct stm32_mbox *mb = container_of(cl, struct stm32_mbox, client); 285 struct stm32_rproc *ddata = rproc->priv; 286 287 queue_work(ddata->workqueue, &mb->vq_work); 288 } 289 290 static void stm32_rproc_free_mbox(struct rproc *rproc) 291 { 292 struct stm32_rproc *ddata = rproc->priv; 293 unsigned int i; 294 295 for (i = 0; i < ARRAY_SIZE(ddata->mb); i++) { 296 if (ddata->mb[i].chan) 297 mbox_free_channel(ddata->mb[i].chan); 298 ddata->mb[i].chan = NULL; 299 } 300 } 301 302 static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = { 303 { 304 .name = STM32_MBX_VQ0, 305 .vq_id = STM32_MBX_VQ0_ID, 306 .client = { 307 .rx_callback = stm32_rproc_mb_callback, 308 .tx_block = false, 309 }, 310 }, 311 { 312 .name = STM32_MBX_VQ1, 313 .vq_id = STM32_MBX_VQ1_ID, 314 .client = { 315 .rx_callback = stm32_rproc_mb_callback, 316 .tx_block = false, 317 }, 318 }, 319 { 320 .name = STM32_MBX_SHUTDOWN, 321 .vq_id = -1, 322 .client = { 323 .tx_block = true, 324 .tx_done = NULL, 325 .tx_tout = 500, /* 500 ms time out */ 326 }, 327 } 328 }; 329 330 static int stm32_rproc_request_mbox(struct rproc *rproc) 331 { 332 struct stm32_rproc *ddata = rproc->priv; 333 struct device *dev = &rproc->dev; 334 unsigned int i; 335 int j; 336 const unsigned char *name; 337 struct mbox_client *cl; 338 339 /* Initialise mailbox structure table */ 340 memcpy(ddata->mb, stm32_rproc_mbox, sizeof(stm32_rproc_mbox)); 341 342 for (i = 0; i < MBOX_NB_MBX; i++) { 343 name = ddata->mb[i].name; 344 345 cl = &ddata->mb[i].client; 346 cl->dev = dev->parent; 347 348 ddata->mb[i].chan = mbox_request_channel_byname(cl, name); 349 if (IS_ERR(ddata->mb[i].chan)) { 350 if (PTR_ERR(ddata->mb[i].chan) == -EPROBE_DEFER) 351 goto err_probe; 352 dev_warn(dev, "cannot get %s mbox\n", name); 353 ddata->mb[i].chan = NULL; 354 } 355 if (ddata->mb[i].vq_id >= 0) { 356 INIT_WORK(&ddata->mb[i].vq_work, 357 stm32_rproc_mb_vq_work); 358 } 359 } 360 361 return 0; 362 363 err_probe: 364 for (j = i - 1; j >= 0; j--) 365 if (ddata->mb[j].chan) 366 mbox_free_channel(ddata->mb[j].chan); 367 return -EPROBE_DEFER; 368 } 369 370 static int stm32_rproc_set_hold_boot(struct rproc *rproc, bool hold) 371 { 372 struct stm32_rproc *ddata = rproc->priv; 373 struct stm32_syscon hold_boot = ddata->hold_boot; 374 struct arm_smccc_res smc_res; 375 int val, err; 376 377 val = hold ? HOLD_BOOT : RELEASE_BOOT; 378 379 if (IS_ENABLED(CONFIG_HAVE_ARM_SMCCC) && ddata->secured_soc) { 380 arm_smccc_smc(STM32_SMC_RCC, STM32_SMC_REG_WRITE, 381 hold_boot.reg, val, 0, 0, 0, 0, &smc_res); 382 err = smc_res.a0; 383 } else { 384 err = regmap_update_bits(hold_boot.map, hold_boot.reg, 385 hold_boot.mask, val); 386 } 387 388 if (err) 389 dev_err(&rproc->dev, "failed to set hold boot\n"); 390 391 return err; 392 } 393 394 static void stm32_rproc_add_coredump_trace(struct rproc *rproc) 395 { 396 struct rproc_debug_trace *trace; 397 struct rproc_dump_segment *segment; 398 bool already_added; 399 400 list_for_each_entry(trace, &rproc->traces, node) { 401 already_added = false; 402 403 list_for_each_entry(segment, &rproc->dump_segments, node) { 404 if (segment->da == trace->trace_mem.da) { 405 already_added = true; 406 break; 407 } 408 } 409 410 if (!already_added) 411 rproc_coredump_add_segment(rproc, trace->trace_mem.da, 412 trace->trace_mem.len); 413 } 414 } 415 416 static int stm32_rproc_start(struct rproc *rproc) 417 { 418 struct stm32_rproc *ddata = rproc->priv; 419 int err; 420 421 stm32_rproc_add_coredump_trace(rproc); 422 423 /* clear remote proc Deep Sleep */ 424 if (ddata->pdds.map) { 425 err = regmap_update_bits(ddata->pdds.map, ddata->pdds.reg, 426 ddata->pdds.mask, 0); 427 if (err) { 428 dev_err(&rproc->dev, "failed to clear pdds\n"); 429 return err; 430 } 431 } 432 433 err = stm32_rproc_set_hold_boot(rproc, false); 434 if (err) 435 return err; 436 437 return stm32_rproc_set_hold_boot(rproc, true); 438 } 439 440 static int stm32_rproc_stop(struct rproc *rproc) 441 { 442 struct stm32_rproc *ddata = rproc->priv; 443 int err, dummy_data, idx; 444 445 /* request shutdown of the remote processor */ 446 if (rproc->state != RPROC_OFFLINE) { 447 idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_SHUTDOWN); 448 if (idx >= 0 && ddata->mb[idx].chan) { 449 /* a dummy data is sent to allow to block on transmit */ 450 err = mbox_send_message(ddata->mb[idx].chan, 451 &dummy_data); 452 if (err < 0) 453 dev_warn(&rproc->dev, "warning: remote FW shutdown without ack\n"); 454 } 455 } 456 457 err = stm32_rproc_set_hold_boot(rproc, true); 458 if (err) 459 return err; 460 461 err = reset_control_assert(ddata->rst); 462 if (err) { 463 dev_err(&rproc->dev, "failed to assert the reset\n"); 464 return err; 465 } 466 467 /* to allow platform Standby power mode, set remote proc Deep Sleep */ 468 if (ddata->pdds.map) { 469 err = regmap_update_bits(ddata->pdds.map, ddata->pdds.reg, 470 ddata->pdds.mask, 1); 471 if (err) { 472 dev_err(&rproc->dev, "failed to set pdds\n"); 473 return err; 474 } 475 } 476 477 return 0; 478 } 479 480 static void stm32_rproc_kick(struct rproc *rproc, int vqid) 481 { 482 struct stm32_rproc *ddata = rproc->priv; 483 unsigned int i; 484 int err; 485 486 if (WARN_ON(vqid >= MBOX_NB_VQ)) 487 return; 488 489 for (i = 0; i < MBOX_NB_MBX; i++) { 490 if (vqid != ddata->mb[i].vq_id) 491 continue; 492 if (!ddata->mb[i].chan) 493 return; 494 err = mbox_send_message(ddata->mb[i].chan, (void *)(long)vqid); 495 if (err < 0) 496 dev_err(&rproc->dev, "%s: failed (%s, err:%d)\n", 497 __func__, ddata->mb[i].name, err); 498 return; 499 } 500 } 501 502 static struct rproc_ops st_rproc_ops = { 503 .start = stm32_rproc_start, 504 .stop = stm32_rproc_stop, 505 .kick = stm32_rproc_kick, 506 .load = rproc_elf_load_segments, 507 .parse_fw = stm32_rproc_parse_fw, 508 .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table, 509 .sanity_check = rproc_elf32_sanity_check, 510 .get_boot_addr = rproc_elf_get_boot_addr, 511 }; 512 513 static const struct of_device_id stm32_rproc_match[] = { 514 { .compatible = "st,stm32mp1-m4" }, 515 {}, 516 }; 517 MODULE_DEVICE_TABLE(of, stm32_rproc_match); 518 519 static int stm32_rproc_get_syscon(struct device_node *np, const char *prop, 520 struct stm32_syscon *syscon) 521 { 522 int err = 0; 523 524 syscon->map = syscon_regmap_lookup_by_phandle(np, prop); 525 if (IS_ERR(syscon->map)) { 526 err = PTR_ERR(syscon->map); 527 syscon->map = NULL; 528 goto out; 529 } 530 531 err = of_property_read_u32_index(np, prop, 1, &syscon->reg); 532 if (err) 533 goto out; 534 535 err = of_property_read_u32_index(np, prop, 2, &syscon->mask); 536 537 out: 538 return err; 539 } 540 541 static int stm32_rproc_parse_dt(struct platform_device *pdev) 542 { 543 struct device *dev = &pdev->dev; 544 struct device_node *np = dev->of_node; 545 struct rproc *rproc = platform_get_drvdata(pdev); 546 struct stm32_rproc *ddata = rproc->priv; 547 struct stm32_syscon tz; 548 unsigned int tzen; 549 int err, irq; 550 551 irq = platform_get_irq(pdev, 0); 552 if (irq == -EPROBE_DEFER) 553 return -EPROBE_DEFER; 554 555 if (irq > 0) { 556 err = devm_request_irq(dev, irq, stm32_rproc_wdg, 0, 557 dev_name(dev), rproc); 558 if (err) { 559 dev_err(dev, "failed to request wdg irq\n"); 560 return err; 561 } 562 563 ddata->wdg_irq = irq; 564 565 if (of_property_read_bool(np, "wakeup-source")) { 566 device_init_wakeup(dev, true); 567 dev_pm_set_wake_irq(dev, irq); 568 } 569 570 dev_info(dev, "wdg irq registered\n"); 571 } 572 573 ddata->rst = devm_reset_control_get_by_index(dev, 0); 574 if (IS_ERR(ddata->rst)) { 575 dev_err(dev, "failed to get mcu reset\n"); 576 return PTR_ERR(ddata->rst); 577 } 578 579 /* 580 * if platform is secured the hold boot bit must be written by 581 * smc call and read normally. 582 * if not secure the hold boot bit could be read/write normally 583 */ 584 err = stm32_rproc_get_syscon(np, "st,syscfg-tz", &tz); 585 if (err) { 586 dev_err(dev, "failed to get tz syscfg\n"); 587 return err; 588 } 589 590 err = regmap_read(tz.map, tz.reg, &tzen); 591 if (err) { 592 dev_err(&rproc->dev, "failed to read tzen\n"); 593 return err; 594 } 595 ddata->secured_soc = tzen & tz.mask; 596 597 err = stm32_rproc_get_syscon(np, "st,syscfg-holdboot", 598 &ddata->hold_boot); 599 if (err) { 600 dev_err(dev, "failed to get hold boot\n"); 601 return err; 602 } 603 604 err = stm32_rproc_get_syscon(np, "st,syscfg-pdds", &ddata->pdds); 605 if (err) 606 dev_info(dev, "failed to get pdds\n"); 607 608 rproc->auto_boot = of_property_read_bool(np, "st,auto-boot"); 609 610 return stm32_rproc_of_memory_translations(rproc); 611 } 612 613 static int stm32_rproc_probe(struct platform_device *pdev) 614 { 615 struct device *dev = &pdev->dev; 616 struct stm32_rproc *ddata; 617 struct device_node *np = dev->of_node; 618 struct rproc *rproc; 619 int ret; 620 621 ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); 622 if (ret) 623 return ret; 624 625 rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata)); 626 if (!rproc) 627 return -ENOMEM; 628 629 rproc->has_iommu = false; 630 ddata = rproc->priv; 631 ddata->workqueue = create_workqueue(dev_name(dev)); 632 if (!ddata->workqueue) { 633 dev_err(dev, "cannot create workqueue\n"); 634 ret = -ENOMEM; 635 goto free_rproc; 636 } 637 638 platform_set_drvdata(pdev, rproc); 639 640 ret = stm32_rproc_parse_dt(pdev); 641 if (ret) 642 goto free_wkq; 643 644 ret = stm32_rproc_request_mbox(rproc); 645 if (ret) 646 goto free_rproc; 647 648 ret = rproc_add(rproc); 649 if (ret) 650 goto free_mb; 651 652 return 0; 653 654 free_mb: 655 stm32_rproc_free_mbox(rproc); 656 free_wkq: 657 destroy_workqueue(ddata->workqueue); 658 free_rproc: 659 if (device_may_wakeup(dev)) { 660 dev_pm_clear_wake_irq(dev); 661 device_init_wakeup(dev, false); 662 } 663 rproc_free(rproc); 664 return ret; 665 } 666 667 static int stm32_rproc_remove(struct platform_device *pdev) 668 { 669 struct rproc *rproc = platform_get_drvdata(pdev); 670 struct stm32_rproc *ddata = rproc->priv; 671 struct device *dev = &pdev->dev; 672 673 if (atomic_read(&rproc->power) > 0) 674 rproc_shutdown(rproc); 675 676 rproc_del(rproc); 677 stm32_rproc_free_mbox(rproc); 678 destroy_workqueue(ddata->workqueue); 679 680 if (device_may_wakeup(dev)) { 681 dev_pm_clear_wake_irq(dev); 682 device_init_wakeup(dev, false); 683 } 684 rproc_free(rproc); 685 686 return 0; 687 } 688 689 static int __maybe_unused stm32_rproc_suspend(struct device *dev) 690 { 691 struct rproc *rproc = dev_get_drvdata(dev); 692 struct stm32_rproc *ddata = rproc->priv; 693 694 if (device_may_wakeup(dev)) 695 return enable_irq_wake(ddata->wdg_irq); 696 697 return 0; 698 } 699 700 static int __maybe_unused stm32_rproc_resume(struct device *dev) 701 { 702 struct rproc *rproc = dev_get_drvdata(dev); 703 struct stm32_rproc *ddata = rproc->priv; 704 705 if (device_may_wakeup(dev)) 706 return disable_irq_wake(ddata->wdg_irq); 707 708 return 0; 709 } 710 711 static SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops, 712 stm32_rproc_suspend, stm32_rproc_resume); 713 714 static struct platform_driver stm32_rproc_driver = { 715 .probe = stm32_rproc_probe, 716 .remove = stm32_rproc_remove, 717 .driver = { 718 .name = "stm32-rproc", 719 .pm = &stm32_rproc_pm_ops, 720 .of_match_table = of_match_ptr(stm32_rproc_match), 721 }, 722 }; 723 module_platform_driver(stm32_rproc_driver); 724 725 MODULE_DESCRIPTION("STM32 Remote Processor Control Driver"); 726 MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>"); 727 MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>"); 728 MODULE_LICENSE("GPL v2"); 729 730