Problem with a driver using the serial core

From: Herve Spitz
Date: Thu Mar 06 2008 - 08:15:24 EST


Hi,

I'm developping a serial driver for a PowerPC target wih a specific uart device, and I've some problem with the use of the serial core.
I've already developed a basic driver for it with simple open, close, read and write functions, but it seems that it's not enough for launching a busybox on this serial port.
So I've decided to try to use the serial core, but the startup function is never reached when I open the device with the open system call in a C program, altough the returned file descriptor is good. I've tried a lot of things and done some searches on the Internet, but I didn't find anywhere the solution of this issue.
I'm using the 2.6.22.6 kernel, and I tried to learn how to use this serial core with the help of a Linux Journal article ( http://www.linuxjournal.com/article/6331 ) and of course with the sources of the built-in serial driver from the kernel.
Here is a part of the code of my driver :

--------- Start of the code ---------
static int epicea_uart_startup(struct uart_port * port){
printk(KERN_INFO "Driver serial: Startup\n");

/* create our timer and submit it */
if (!timer) {
timer = kmalloc (sizeof (*timer), GFP_KERNEL);
if (!timer)
return -ENOMEM;
}
init_timer(timer);
timer->data = (unsigned long) port;
timer->expires = jiffies + DELAY_TIME;
timer->function = epicea_uart_timer;
add_timer (timer);

return 0;
}

static struct uart_ops epicea_uart_ops = {
.tx_empty = epicea_uart_tx_empty,
.set_mctrl = epicea_uart_set_mctrl,
.get_mctrl = epicea_uart_get_mctrl,
.stop_tx = epicea_uart_stop_tx,
.start_tx = epicea_uart_start_tx,
.stop_rx = epicea_uart_stop_rx,
.enable_ms = epicea_uart_enable_ms,
.break_ctl = epicea_uart_break_ctl,
.startup = epicea_uart_startup,
.shutdown = epicea_uart_shutdown,
.set_termios = epicea_uart_change_speed,
.type = epicea_uart_type,
.release_port = epicea_uart_release_port,
.request_port = epicea_uart_request_port,
.config_port = epicea_uart_config_port,
.verify_port = epicea_uart_verify_port,
};

static struct uart_port epicea_uart_port = {
.ops = &epicea_uart_ops,
};

static struct uart_driver epicea_uart_reg = {
.owner = THIS_MODULE,
.driver_name = "driver_serial",
.dev_name = EPICEA_UART_DEVNAME,
.major = EPICEA_UART_MAJOR,
.minor = 1,
.nr = 1,
};

static int __init epicea_uart_init(void){
int result;

printk(KERN_INFO "Driver serial: Module init...");

result = uart_register_driver(&epicea_uart_reg);
if (result){
printk(KERN_INFO " [FAILED]\nDriver serial: Uart register driver failed\n");
return result;
}

result = uart_add_one_port(&epicea_uart_reg,&epicea_uart_port);
if (result){
printk(KERN_INFO " [FAILED]\nDriver serial: Uart add one port failed\n");
return result;
}

printk(KERN_INFO " [ OK ]\n");
return result;
}
--------- End of the code ---------

Any idea ?

Thanks in advance for your help.

Best regards,

Hervé Spitz
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/