Может читать только 0 из памяти ioremap()
Я разрабатываю простой драйвер для Linux, который будет общаться с устройством через SPI. После того, как я использую request_mem_region и ioremap, все, что я могу прочитать по возвращенному адресу, равно 0, даже после того, как я записал в него значение. Адрес со смещением 0 должен быть регистром управления для контроллера SPI (это SoC Xilinx Zynq). Регистр управления устанавливается с начальным значением во время процесса загрузки.
Код:
int device_init() {
int ret;
ret = register_chrdev(device_major, DEVICE_NAME, &fops);
if(ret < 0) {
printk(KERN_ALERT "spi: cannot obtain major number %d.\n", device_major);
return ret;
}
if(request_mem_region (SPI_ADDR, SPI_SIZE, "SPI Driver") == NULL)
{
printk("Failed to request memory region!\n");
device_exit();
return 1;
}
spi = ioremap(SPI_ADDR, SPI_SIZE);
if(spi == NULL)
{
printk("I/O remap failed\n");
device_exit();
return 1;
}
printk("Driver init complete. Mapped to address 0x%X\n", spi);
iowrite32be(0x20000, spi);
printk("%X\n", ioread32be(spi));
return 0;
}
Выход, когда я вставляю модуль:
Инициализация драйвера завершена. Отображен на адрес 0xE08C2000
0
Заранее благодарю за любую помощь.
1 ответ
Я думаю, что это может быть так, поэтому я помещаю это в ответ. Я знаком с Xilinx в целом, но не с ядром SPI специально. Я только что посмотрел на основные данные Xilinx SPI. Таблица 4 на стр. 8 содержит сводную информацию о регистрах. Регистров по базовому адресу нет. Я не уверен, почему ядро вообще отвечает на базовый адрес, но, возможно, оно жестко запрограммировано в 0.
В любом случае, после ioremap()
попробуй это:
void *ipier;
ipier = spi + 0x28;
printk("Driver init complete. Mapped to address 0x%X\n", spi);
iowrite32be(0x20000, ipier);
printk("%X\n", ioread32be(ipier));
Это, конечно, предполагает, что регистр IPIER не удаляется из ядра IP из-за каких-то настроек, конечно.
Редактировать: Согласно комментарию ниже, операционная система не использует IP-ядро SPI, так что это не ответ на вопрос.