The following series of patches implements a USB Type-C Port Manager using the pending USB Type-C class code as basis. The code is still WIP (I am still waiting for a final decision on locking in the class code), but I think it is important to get feedback from the community at this point. There are four patches in the series. The first two patches remove locking from the Type-C class code. The third patch implements the Type-C Port Manager state machine. The forth patch is an interface between the Type-C Port Manager and a TCPCI (Type-C Port Controller Interface) compliant USB Type-C Port Controller. Patch 4/4 (the interface to a TCPCI compliant chip) is currently untested since I don't have the necessary hardware available. The port manager code was tested connecting to an Embedded Controller on a Chromebook, bypassing the Port Manager implementation in the EC. Both Source and Sink operation was tested with various Type-C chargers, docks, and connectors. Alternate mode support is partially implemented (Alternate mode support is requested from the partner), but alternate modes are actually selected. Implementing this will require more thought, since the actual alternate mode support has to be implemented elsewhere, such as in a dedicated Phy driver. It should be possible to implement the interface between phy driver and Type-C Port Controller driver using extcon, but I have not further explored the possibilities, and other options might be possible and/or better. Why remove locking from the Type-C class code ? The primary problem is that Type-C state and role changes are triggered by the Port Manager state machine and quite independent from role change requests triggered by or requested through the class code. At the same time, the code handling role change requests triggered from the class code has to wait for the role change to complete before returning to the class code. This can result in a deadlock, since the state machine also needs to report unsolicited role (or status) changes to the class code. Consider this situation: - User requests a role change throuch class code. - Class code acquires mutex, and passes role change request to port manager. - Port manager attempts to acquire its port mutex. Port state machine is active, causing the code to stall. - Port state machine executes a state change or role change request from the port partner. Upon completion, it attempts to inform the class that a role or state change occurred. It does so while the port mutex is active to prevent state changes while the state machine is still running. - The callback into the class code waits for the class mutex, which is locked because there is also a role change request from the class code pending. Instead of trying to handle the situation in low level drivers by trying to avoid deadlocks, it seems better to leave all locking to low level drivers to start with. Since low level drivers are in control of port changes and port roles, this appears to be the simpler approach. I am open to listen to other ideas, though. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html