Мне кажется, что у вас есть деление на ноль в функции davinci_spi_cpufreq_transition(). Где-то в этой функции (или в какой-то функции, которая вызывается в davinci_spi_cpufreq_transition) есть ошибочная операция деления, которая пытается разделить на некоторую переменную, которая (в вашем случае) имеет значение 0. И это очевидно, ошибка, которая должна быть правильно обработана в коде, но на самом деле это не так.
Трудно сказать, какой именно код приводит к этому, потому что я не знаю, какое ядро вы используете. Было бы намного проще, если бы вы предоставили ссылку на репозиторий вашего ядра. Хотя я не смог найти davinci_spi_cpufreq_transition в основном ядре, я нашел его здесь.
функция davinci_spi_cpufreq_transition() находится в drivers/spi/davinci_spi.c. Он вызывает функцию davinci_spi_calc_clk_div(). Там действуют 2 дивизии. Во-первых:
prescale = ((clk_rate / hz) - 1);
И второе это:
if (hz < (clk_rate / (prescale + 1)))
Один из них, вероятно, вызывает ошибку «деление на ноль». Я предлагаю вам отследить, какой именно, изменив функцию davinci_spi_calc_clk_div() следующим образом (просто добавьте строки, отмеченные знаком "+"):
static void davinci_spi_calc_clk_div(struct davinci_spi *davinci_spi)
{
struct davinci_spi_platform_data *pdata;
unsigned long clk_rate;
u32 hz, cs_num, prescale;
pdata = davinci_spi->pdata;
cs_num = davinci_spi->cs_num;
hz = davinci_spi->speed;
clk_rate = clk_get_rate(davinci_spi->clk);
+ printk(KERN_ERR "### hz = %u\n", hz);
prescale = ((clk_rate / hz) - 1);
if (prescale > 0xff)
prescale = 0xff;
+ printk("### prescale + 1 = %u\n", prescale + 1UL);
if (hz < (clk_rate / (prescale + 1)))
prescale++;
if (prescale < 2) {
pr_info("davinci SPI controller min. prescale value is 2\n");
prescale = 2;
}
clear_fmt_bits(davinci_spi->base, 0x0000ff00, cs_num);
set_fmt_bits(davinci_spi->base, prescale << 8, cs_num);
}
Мое предположение - это переменная "hz", которая в вашем случае равна 0. Если это так, вы также можете добавить следующую строку отладки в функцию davinci_spi_setup_transfer():
if (!hz)
hz = spi->max_speed_hz;
+ printk(KERN_ERR "### setup_transfer: setting speed to %u\n", hz);
davinci_spi->speed = hz;
davinci_spi->cs_num = spi->chip_select;
Со всеми этими изменениями пересоберите ядро, и вы, вероятно, поймете, почему у вас возникает эта ошибка "div by zero". Просто найдите строки, начинающиеся с "###" в журнале загрузки вашего ядра. Если вы не знаете, что делать дальше — прикрепите эти отладочные строки, и я постараюсь вам помочь.
person
Sam Protsenko
schedule
27.01.2015