Merge "usb: reattempt to enter displayport alt mode if driver entry process fails" into main

This commit is contained in:
RD Babiera 2023-11-17 22:12:05 +00:00 committed by Android (Google) Code Review
commit c92ee8d02a
2 changed files with 74 additions and 3 deletions

View file

@ -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, &currentPortStatus);
} 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:

View file

@ -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;