AW: Simple write to an UART mode register fails

Frey ext-FA, Maurus maurus.frey.ext at siemens.com
Thu Mar 3 12:01:29 EST 2011


Salut Thomas,

Thanks! Your answer is appreciated. 

I know that what I'm trying to do seems to weird and does not follow the
best practice I've learned. But currently it's not the appropriate
moment to do such changes in board kernel. So I have to provide a quick
solution with a LKM. 

> 
> I haven't look into many details, but I don't see why you need a
> specific driver to do this. The Atmel serial driver in
> drivers/serial/atmel_serial.c already supports RS485.
> 
> So from what I can see, all you need to do is to add some details in
> the platform_data structure relative to the serial port. So probably
> you need to change the uart3_data structure in
> arch/arm/mach-at91/at91sam9260_devices.c, by adding a .rs485 field :
> 
> static struct atmel_uart_data uart3_data = {
>         .use_dma_tx     = 1,
>         .use_dma_rx     = 1,
> 	.rs485		= {
> 			/* Fill the fields of the serial_rs485 structure
> 			   defined in include/linux/serial.h */
> 	},
> };
Sorry when I wasn't precise enough in my explanation: Finally I want
choose if this UART should be associated with the serial-driver
(according to the device model) or with another not-tty driver. That's
why I allow to change platform_device.name in the LKM. 

Anyway the 2.6.32 atmel_serial driver doesn't support the RS485 mode. As
mentioned before I'm currently not "able" to back-port the most recent
driver. 
http://lxr.free-electrons.com/source/drivers/serial/atmel_serial.c?v=2.6
.32;a=arm

> 
> To configure the pins, you have to call at91_register_uart() in the
> ek_map_io() function of your board file  (presumably
> arch/arm/mach-at91/board-at91sam9261ek.c). The third parameter allows
> to tell which pins should be configured. For example, if you pass
> ATMEL_UART_RTS, then the code in
> arch/arm/mach-at91/at91sam9260_devices.c will do:
> 
>         if (pins & ATMEL_UART_RTS)
>                 at91_set_B_periph(AT91_PIN_PC8, 0);     /* RTS3 */
> 
> see the function configure_usart3_pins().

Yes, that's where I got at91_set_X_periph() from.

> 
> I don't know how this can even compile: at91_register_uart() 
> returns an
> int, and pdev is a platform_device * is your code.

Sorry: I forgot to mention that at91_register_uart() has been patched to
return platform_device*. Without it wouldn't be possible to compile. I
didn't post the full context. 

> 
> I'm sorry but this code really isn't implemented with the driver model
> in mind. That's not how things are supposed to work.

It's "bricolage", I know. I'm urged to wrest this device out of the
driver model, to use it with a specific driver. 

> And also, your code is completely wrapped, which makes it 
> impossible to
> read.

I thought that to post the entire lkm code would be better than
partially post it... Wrong choice related to the line wrapping. 

Thanks for your help.

Regards

maurus

> 
> It's the board/SoC code (in your case
> arch/arm/mach-at91/board-at91sam9261ek.c and
> arch/arm/mach-at91/at91sam9260_devices.c) that instantiates the
> platform_device structure and does the pin muxing. Each 
> platform_device
> structure can receive driver-specific information in the platform_data
> field, such as the ones needed here for RS485. You really don't need a
> separate kernel module to do this, just modify your board/SoC file (in
> this case you'll have to modify the SoC file, as the
> at91_add_device_serial() function doesn't allow to pass the
> UART-specific platform_data, unlike what is done with the other
> at91_add_device_*() functions).
> 
> Regards,
> 
> Thomas
> -- 
> Thomas Petazzoni, Free Electrons
> Kernel, drivers, real-time and embedded Linux
> development, consulting, training and support.
> http://free-electrons.com



More information about the Kernelnewbies mailing list