mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-19 01:40:17 +00:00
DM: virtio-gpio: support reading value from IRQ descriptor
Support reading GPIO value when the GPIO switches to IRQ mode. Tracked-On: #2512 Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
d34b3ebdd0
commit
83a98acb1b
@ -250,6 +250,7 @@ struct gpio_irq_desc {
|
|||||||
int fd; /* read event */
|
int fd; /* read event */
|
||||||
int pin; /* pin number */
|
int pin; /* pin number */
|
||||||
bool mask; /* mask and unmask */
|
bool mask; /* mask and unmask */
|
||||||
|
bool deinit; /* deinit state */
|
||||||
uint8_t level; /* level value */
|
uint8_t level; /* level value */
|
||||||
uint64_t mode; /* interrupt trigger mode */
|
uint64_t mode; /* interrupt trigger mode */
|
||||||
void *data; /* virtio gpio instance */
|
void *data; /* virtio gpio instance */
|
||||||
@ -401,17 +402,32 @@ gpio_get_value(struct virtio_gpio *gpio, unsigned int offset)
|
|||||||
{
|
{
|
||||||
struct gpio_line *line;
|
struct gpio_line *line;
|
||||||
struct gpiohandle_data data;
|
struct gpiohandle_data data;
|
||||||
int rc;
|
int rc, fd;
|
||||||
|
|
||||||
line = gpio->vlines[offset];
|
line = gpio->vlines[offset];
|
||||||
if (line->busy || line->fd < 0) {
|
if (line->busy) {
|
||||||
DPRINTF("failed to get gpio%d value, busy:%d, fd:%d\n",
|
DPRINTF("failed to get gpio %d value, it is busy\n", offset);
|
||||||
offset, line->busy, line->fd);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fd = line->fd;
|
||||||
|
if (fd < 0) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the GPIO line has configured as IRQ mode, then can't use
|
||||||
|
* gpio line fd to get its value, instead, use IRQ fd to get
|
||||||
|
* the value.
|
||||||
|
*/
|
||||||
|
if (line->irq->fd < 0) {
|
||||||
|
DPRINTF("failed to get gpio %d value, fd is invalid\n",
|
||||||
|
offset);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fd = line->irq->fd;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
rc = ioctl(line->fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
|
rc = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
DPRINTF("ioctl GPIOHANDLE_GET_LINE_VALUES_IOCTL error %s\n",
|
DPRINTF("ioctl GPIOHANDLE_GET_LINE_VALUES_IOCTL error %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@ -951,6 +967,7 @@ gpio_irq_disable(struct gpio_irq_chip *chip, unsigned int pin)
|
|||||||
|
|
||||||
/* Release the mevent, mevent teardown handles IRQ desc reset */
|
/* Release the mevent, mevent teardown handles IRQ desc reset */
|
||||||
if (desc->mevt) {
|
if (desc->mevt) {
|
||||||
|
desc->deinit = false;
|
||||||
mevent_delete(desc->mevt);
|
mevent_delete(desc->mevt);
|
||||||
desc->mevt = NULL;
|
desc->mevt = NULL;
|
||||||
}
|
}
|
||||||
@ -970,6 +987,10 @@ gpio_irq_teardown(void *param)
|
|||||||
close(desc->fd);
|
close(desc->fd);
|
||||||
desc->fd = -1;
|
desc->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if deinit is not set, switch the pin to GPIO mode */
|
||||||
|
if (!desc->deinit)
|
||||||
|
native_gpio_open_line(desc->gpio, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1168,6 +1189,7 @@ gpio_irq_deinit(struct virtio_gpio *gpio)
|
|||||||
for (i = 0; i < gpio->nvline; i++) {
|
for (i = 0; i < gpio->nvline; i++) {
|
||||||
desc = &chip->descs[i];
|
desc = &chip->descs[i];
|
||||||
if (desc->mevt) {
|
if (desc->mevt) {
|
||||||
|
desc->deinit = true;
|
||||||
mevent_delete(desc->mevt);
|
mevent_delete(desc->mevt);
|
||||||
desc->mevt = NULL;
|
desc->mevt = NULL;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user