From: Barry Song 21cnbao@gmail.com
The newest compiliers can optimize pll calculation in several codecs into __aeabi__uldivmod which doesn't exist in kernel. Then the link will fail: ERROR: "__aeabi_uldivmod" [sound/soc/codecs/snd-soc-wm8974.ko] undefined! ERROR: "__aeabi_uldivmod" [sound/soc/codecs/snd-soc-wm8940.ko] undefined! ERROR: "__aeabi_uldivmod" [sound/soc/codecs/snd-soc-wm8510.ko] undefined! This patch prevent the optimizaton by insert ASM.
Signed-off-by: Barry Song 21cnbao@gmail.com Cc: Zhiwu Song zhiwu.song@csr.com Cc: Binghua Duan binghua.duan@csr.com --- sound/soc/codecs/wm8510.c | 6 ++++++ sound/soc/codecs/wm8940.c | 6 ++++++ sound/soc/codecs/wm8974.c | 6 ++++++ 3 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index db0dced..a636b15 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -258,6 +258,12 @@ static void pll_factors(unsigned int target, unsigned int source) Nmod = target % source; Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+ /* + * The following asm() prevents the compiler from optimising + * into a standard EABI function __aeabi__uldivmod() + */ + asm("" : "+r"(source)); + do_div(Kpart, source);
K = Kpart & 0xFFFFFFFF; diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 25580e3..f6148af 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -520,6 +520,12 @@ static void pll_factors(unsigned int target, unsigned int source) Nmod = target % source; Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+ /* + * The following asm() prevents the compiler from optimising + * into a standard EABI function __aeabi__uldivmod() + */ + asm("" : "+r"(source)); + do_div(Kpart, source);
K = Kpart & 0xFFFFFFFF; diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index ca646a8..c9036d9 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -317,6 +317,12 @@ static void pll_factors(struct pll_ *pll_div, Nmod = target % source; Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+ /* + * The following asm() prevents the compiler from optimising + * into a standard EABI function __aeabi__uldivmod() + */ + asm("" : "+r"(source)); + do_div(Kpart, source);
K = Kpart & 0xFFFFFFFF;