Merge "usb: reattempt to enter displayport alt mode if driver entry process fails" into main
This commit is contained in:
commit
c92ee8d02a
2 changed files with 74 additions and 3 deletions
|
@ -560,6 +560,11 @@ Usb::Usb()
|
|||
ALOGE("mDisplayPortDebounceTimer timerfd failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
mDisplayPortActivateTimer = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
|
||||
if (mDisplayPortActivateTimer == -1) {
|
||||
ALOGE("mDisplayPortActivateTimer timerfd failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
ScopedAStatus Usb::switchRole(const string& in_portName, const PortRole& in_role,
|
||||
|
@ -1721,6 +1726,10 @@ static int displayPortPollOpenFileHelper(const char *file, int flags) {
|
|||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* armTimerFdHelper - Sets timerfd (fd) to trigger after (ms) milliseconds.
|
||||
* Setting ms to 0 disarms the timer.
|
||||
*/
|
||||
static int armTimerFdHelper(int fd, int ms) {
|
||||
struct itimerspec ts;
|
||||
|
||||
|
@ -1733,23 +1742,31 @@ static int armTimerFdHelper(int fd, int ms) {
|
|||
}
|
||||
|
||||
void *displayPortPollWork(void *param) {
|
||||
/* USB Payload */
|
||||
::aidl::android::hardware::usb::Usb *usb = (::aidl::android::hardware::usb::Usb *)param;
|
||||
/* Epoll fields */
|
||||
int epoll_fd;
|
||||
struct epoll_event ev_hpd, ev_pin, ev_orientation, ev_eventfd, ev_link, ev_debounce;
|
||||
struct epoll_event ev_activate;
|
||||
int nevents = 0;
|
||||
int hpd_fd, pin_fd, orientation_fd, link_training_status_fd;
|
||||
int file_flags = O_RDONLY;
|
||||
int epoll_flags;
|
||||
/* DisplayPort link statuses */
|
||||
bool orientationSet = false;
|
||||
bool pinSet = false;
|
||||
int activateRetryCount = 0;
|
||||
unsigned long res;
|
||||
int ret = 0;
|
||||
/* File paths */
|
||||
string displayPortUsbPath, irqHpdCountPath, hpdPath, pinAssignmentPath, orientationPath;
|
||||
string tcpcI2cBus, linkPath;
|
||||
::aidl::android::hardware::usb::Usb *usb = (::aidl::android::hardware::usb::Usb *)param;
|
||||
string tcpcI2cBus, linkPath, partnerActivePath, portActivePath;
|
||||
|
||||
usb->mDisplayPortPollRunning = true;
|
||||
usb->mDisplayPortPollStarting = false;
|
||||
|
||||
/*---------- Setup ----------*/
|
||||
|
||||
if (usb->getDisplayPortUsbPathHelper(&displayPortUsbPath) == Status::ERROR) {
|
||||
ALOGE("usbdp: worker: could not locate usb displayport directory");
|
||||
goto usb_path_error;
|
||||
|
@ -1761,6 +1778,9 @@ void *displayPortPollWork(void *param) {
|
|||
orientationPath = "/sys/class/typec/port0/orientation";
|
||||
linkPath = string(kDisplayPortDrmPath) + "link_status";
|
||||
|
||||
partnerActivePath = displayPortUsbPath + "../mode1/active";
|
||||
portActivePath = "/sys/class/typec/port0/port0.0/mode1/active";
|
||||
|
||||
getI2cBusHelper(&tcpcI2cBus);
|
||||
irqHpdCountPath = kI2CPath + tcpcI2cBus + "/" + tcpcI2cBus + kIrqHpdCounPath;
|
||||
ALOGI("usbdp: worker: irqHpdCountPath:%s", irqHpdCountPath.c_str());
|
||||
|
@ -1793,12 +1813,15 @@ void *displayPortPollWork(void *param) {
|
|||
ev_eventfd.events = epoll_flags;
|
||||
ev_link.events = epoll_flags;
|
||||
ev_debounce.events = epoll_flags;
|
||||
ev_activate.events = epoll_flags;
|
||||
|
||||
ev_hpd.data.fd = hpd_fd;
|
||||
ev_pin.data.fd = pin_fd;
|
||||
ev_orientation.data.fd = orientation_fd;
|
||||
ev_eventfd.data.fd = usb->mDisplayPortEventPipe;
|
||||
ev_link.data.fd = link_training_status_fd;
|
||||
ev_debounce.data.fd = usb->mDisplayPortDebounceTimer;
|
||||
ev_activate.data.fd = usb->mDisplayPortActivateTimer;
|
||||
|
||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, hpd_fd, &ev_hpd) == -1) {
|
||||
ALOGE("usbdp: worker: epoll_ctl failed to add hpd; errno=%d", errno);
|
||||
|
@ -1817,7 +1840,11 @@ void *displayPortPollWork(void *param) {
|
|||
goto error;
|
||||
}
|
||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortDebounceTimer, &ev_debounce) == -1) {
|
||||
ALOGE("usbdp: worker: epoll_ctl failed to add debounce; errno=%d", errno);
|
||||
ALOGE("usbdp: worker: epoll_ctl failed to add framework update debounce; errno=%d", errno);
|
||||
goto error;
|
||||
}
|
||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortActivateTimer, &ev_activate) == -1) {
|
||||
ALOGE("usbdp: worker: epoll_ctl failed to add activate debounce; errno=%d", errno);
|
||||
goto error;
|
||||
}
|
||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, usb->mDisplayPortEventPipe, &ev_eventfd) == -1) {
|
||||
|
@ -1825,6 +1852,9 @@ void *displayPortPollWork(void *param) {
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* Arm timer to see if DisplayPort Alt Mode Activates */
|
||||
armTimerFdHelper(usb->mDisplayPortActivateTimer, DISPLAYPORT_ACTIVATE_DEBOUNCE_MS);
|
||||
|
||||
while (!destroyDisplayPortThread) {
|
||||
struct epoll_event events[64];
|
||||
|
||||
|
@ -1874,6 +1904,33 @@ void *displayPortPollWork(void *param) {
|
|||
if (ret < 0)
|
||||
ALOGE("usbdp: debounce read errno:%d", errno);
|
||||
queryVersionHelper(usb, ¤tPortStatus);
|
||||
} else if (events[n].data.fd == usb->mDisplayPortActivateTimer) {
|
||||
string activePartner, activePort;
|
||||
|
||||
if (ReadFileToString(partnerActivePath.c_str(), &activePartner) &&
|
||||
ReadFileToString(portActivePath.c_str(), &activePort)) {
|
||||
// Retry activate signal when DisplayPort Alt Mode is active on port but not
|
||||
// partner.
|
||||
if (!strncmp(activePartner.c_str(), "no", strlen("no")) &&
|
||||
!strncmp(activePort.c_str(), "yes", strlen("yes")) &&
|
||||
activateRetryCount < DISPLAYPORT_ACTIVATE_MAX_RETRIES) {
|
||||
if (!WriteStringToFile("1", partnerActivePath)) {
|
||||
ALOGE("usbdp: Failed to activate port partner Alt Mode");
|
||||
} else {
|
||||
ALOGI("usbdp: Attempting to activate port partner Alt Mode");
|
||||
}
|
||||
activateRetryCount++;
|
||||
armTimerFdHelper(usb->mDisplayPortActivateTimer,
|
||||
DISPLAYPORT_ACTIVATE_DEBOUNCE_MS);
|
||||
} else {
|
||||
ALOGI("usbdp: DisplayPort Alt Mode is active, or disabled on port");
|
||||
}
|
||||
} else {
|
||||
activateRetryCount++;
|
||||
armTimerFdHelper(usb->mDisplayPortActivateTimer,
|
||||
DISPLAYPORT_ACTIVATE_DEBOUNCE_MS);
|
||||
ALOGE("usbdp: Failed to read active state from port or partner");
|
||||
}
|
||||
} else if (events[n].data.fd == usb->mDisplayPortEventPipe) {
|
||||
uint64_t flag = 0;
|
||||
if (!read(usb->mDisplayPortEventPipe, &flag, sizeof(flag))) {
|
||||
|
@ -1895,6 +1952,8 @@ void *displayPortPollWork(void *param) {
|
|||
}
|
||||
|
||||
error:
|
||||
/* Need to disarm so new threads don't get old event */
|
||||
armTimerFdHelper(usb->mDisplayPortActivateTimer, 0);
|
||||
close(link_training_status_fd);
|
||||
link_training_status_fd_error:
|
||||
close(orientation_fd);
|
||||
|
@ -1904,6 +1963,7 @@ pin_fd_error:
|
|||
close(hpd_fd);
|
||||
hpd_fd_error:
|
||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortDebounceTimer, &ev_debounce);
|
||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortActivateTimer, &ev_activate);
|
||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, usb->mDisplayPortEventPipe, &ev_eventfd);
|
||||
close(epoll_fd);
|
||||
epoll_fd_error:
|
||||
|
|
|
@ -32,6 +32,13 @@
|
|||
#define PORT_TYPE_TIMEOUT 8
|
||||
#define DISPLAYPORT_CAPABILITIES_RECEPTACLE_BIT 6
|
||||
#define DISPLAYPORT_STATUS_DEBOUNCE_MS 2000
|
||||
/*
|
||||
* Type-C HAL should wait 2 seconds to reattempt DisplayPort Alt Mode entry to
|
||||
* allow the port and port partner to settle Role Swaps.
|
||||
*/
|
||||
#define DISPLAYPORT_ACTIVATE_DEBOUNCE_MS 2000
|
||||
// Number of times the HAL should reattempt to enter DisplayPort Alt Mode
|
||||
#define DISPLAYPORT_ACTIVATE_MAX_RETRIES 2
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
|
@ -173,6 +180,10 @@ struct Usb : public BnUsb {
|
|||
* sending notifications to the frameworks layer.
|
||||
*/
|
||||
int mDisplayPortDebounceTimer;
|
||||
/*
|
||||
* eventfd to monitor whether a connection results in DisplayPort Alt Mode activating.
|
||||
*/
|
||||
int mDisplayPortActivateTimer;
|
||||
|
||||
private:
|
||||
pthread_t mPoll;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue