Re: Lessons learnt from using serdev with SC16IS7XX

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am 26.07.2018 um 16:33 schrieb Rob Herring:
> On Wed, Jul 25, 2018 at 2:55 AM Michael Allwright <allsey87@xxxxxxxxx> wrote:
>>
>> In some hardware I am developing, I have used the SC16IS7XX to connect
>> two AVR microcontrollers back to my main processor running Linux.
>> These microcontrollers implement an control interface which is
>> modelled in Linux as a multi-function device. The set up is based on
>> the driver for the RAVE Supervisory Processor:
>> https://lwn.net/Articles/724765/
> 
> The SC16IS7XX is a popular topic suddenly[1].
> 
>> One issue during initialisation when using serdev with SC16IS7XX is
>> that after uart_add_one_port has been called, the child driver may be
>> started on a different kernel thread and may start calling the startup
>> or set_termios functions of the serial driver before it has finished
>> probing. I temporarily resolved this issue with a hack which involved
>> adding a "ready" boolean to the driver. However, there are two proper
>> solutions to this problem that I can think of: either serdev should
>> somehow check that the probe was completed (successfully) before
>> trying to load child drivers or the SC16IS7XX should have a mutex that
>> better enforces the order in which its functions are called
>> (particularly during initialization). My testing suggests that the
>> latter may be the better solution, since even outside of the
>> initialization context and when using the two ttys heavily at the same
>> time, it is not hard to knock the SC16IS7XX device into a state where,
>> at a minimum, the silicon stops sending interrupts. I think this
>> ordering of function calls may also be partly responsible for
>> "sc16is7xx 1-0048: ttySC0: Unexpected interrupt: 8" kernel messages
>> that are mentioned in other threads.
>>
>> To support multiple ttys on a single device, the serdev code and its
>> DT binding need to be slightly modified. My solution is to modify the
>> code to parse the following:
>>
>> uart56: sc16is762@48 {
>>    compatible = "nxp,sc16is762";
>>    reg = <0x48>;
>>    clocks = <&some_clock>;
>>    interrupt-parent = <&some_gpio_controller>;
>>    interrupts = <X IRQ_TYPE_EDGE_FALLING>;
>>
>>    #address-cells = <1>;
>>    #size-cells = <0>;
>>
>>    uart0: serial@0 {
>>       reg = <0>;
>>       uc0: microcontroller {
> 
> This structure is what I suggested to Andreas.
> 
>>          compatible = "atmel,atmega328p";
>>          current-speed = <57600>;
>>       };
>>    };
>>
>>    uart1: serial@1 {
>>       reg = <1>;
>>       uc1: microcontroller {
>>          compatible = "atmel,atmega328p";
>>          current-speed = <57600>;
>>       };
>>    };
>> };
>>
>> The code to parse this is as follows and uses the tty_idx to indicate
>> which of the sc16is7xx ttys we are referring to. This works nicely
>> with a single chip, however, when you have more than one sc16is7xx
>> device, the reg value needs to be 2 and 3 for the second chip instead
>> 0 and 1 as with the first chip. The second thing that is not so nice
>> about this solution is that I needed to move struct serport from
>> drivers/tty/serdev/serdev-ttyport.c to include/linux/serdev.h so that
>> I could access tty_idx from drivers/tty/serdev/core.c.
> 
> This is a problem.
> 
> This needs to be solved by having the serdev ctrlr DT node be uart0/1
> nodes rather than the parent node. Then the current core code should
> work and you don't need reg to equal the tty index which is wrong.

I had stared at the sc16is7xx code without spotting an obvious way how
to implement that. I know how to obtain a child of_node, but the
uart_port actually stores a full dev pointer. Are you suggesting we have
three different devices, 1 spi_device, N whatever for the ports? If so,
how to create them? As long as dev_get_drvdata() still returns the
expected struct I think it could work then.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux