root/drivers/remoteproc/stm32_rproc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. stm32_rproc_pa_to_da
  2. stm32_rproc_mem_alloc
  3. stm32_rproc_mem_release
  4. stm32_rproc_of_memory_translations
  5. stm32_rproc_mbox_idx
  6. stm32_rproc_elf_load_rsc_table
  7. stm32_rproc_parse_fw
  8. stm32_rproc_wdg
  9. stm32_rproc_mb_callback
  10. stm32_rproc_free_mbox
  11. stm32_rproc_request_mbox
  12. stm32_rproc_set_hold_boot
  13. stm32_rproc_add_coredump_trace
  14. stm32_rproc_start
  15. stm32_rproc_stop
  16. stm32_rproc_kick
  17. stm32_rproc_get_syscon
  18. stm32_rproc_parse_dt
  19. stm32_rproc_probe
  20. stm32_rproc_remove

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

/* [<][>][^][v][top][bottom][index][help] */