Commit 81c484376353251ba13b7ea987a15a896b3d106a

Authored by Christophe Kerello
Committed by Heiko Schocher
1 parent c4e5990ad2

i2c: stm32f7_i2c: fix data abort

As "v" is a local variable in stm32_i2c_choose_solution()
"v" has to be copied into "s" to avoid data abort in
stm32_i2c_compute_timing().

Signed-off-by: Christophe Kerello <christophe.kerello@st.com>
Reviewed-by: Patrick DELAUNAY <patrick.delaunay@st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>

Showing 1 changed file with 11 additions and 10 deletions Side-by-side Diff

drivers/i2c/stm32f7_i2c.c
... ... @@ -571,6 +571,7 @@
571 571 u32 dnf_delay;
572 572 u32 tsync;
573 573 u16 l, h;
  574 + bool sol_found = false;
574 575 int ret = 0;
575 576  
576 577 af_delay_min = setup->analog_filter ?
577 578  
... ... @@ -619,14 +620,15 @@
619 620 clk_error_prev = clk_error;
620 621 v->scll = l;
621 622 v->sclh = h;
622   - s = v;
  623 + sol_found = true;
  624 + memcpy(s, v, sizeof(*s));
623 625 }
624 626 }
625 627 }
626 628 }
627 629 }
628 630  
629   - if (!s) {
  631 + if (!sol_found) {
630 632 pr_err("%s: no solution at all\n", __func__);
631 633 ret = -EPERM;
632 634 }
... ... @@ -638,7 +640,7 @@
638 640 struct stm32_i2c_setup *setup,
639 641 struct stm32_i2c_timings *output)
640 642 {
641   - struct stm32_i2c_timings *v, *_v, *s;
  643 + struct stm32_i2c_timings *v, *_v, s;
642 644 struct list_head solutions;
643 645 int ret;
644 646  
645 647  
646 648  
... ... @@ -669,21 +671,20 @@
669 671 return -EINVAL;
670 672 }
671 673  
672   - s = NULL;
673 674 INIT_LIST_HEAD(&solutions);
674 675 ret = stm32_i2c_compute_solutions(setup, &solutions);
675 676 if (ret)
676 677 goto exit;
677 678  
678   - ret = stm32_i2c_choose_solution(setup, &solutions, s);
  679 + ret = stm32_i2c_choose_solution(setup, &solutions, &s);
679 680 if (ret)
680 681 goto exit;
681 682  
682   - output->presc = s->presc;
683   - output->scldel = s->scldel;
684   - output->sdadel = s->sdadel;
685   - output->scll = s->scll;
686   - output->sclh = s->sclh;
  683 + output->presc = s.presc;
  684 + output->scldel = s.scldel;
  685 + output->sdadel = s.sdadel;
  686 + output->scll = s.scll;
  687 + output->sclh = s.sclh;
687 688  
688 689 debug("%s: Presc: %i, scldel: %i, sdadel: %i, scll: %i, sclh: %i\n",
689 690 __func__, output->presc,