aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index e0f4c3d9649c..94398f89e600 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1841,9 +1841,6 @@ static int ftdi_gpio_request(struct gpio_chip *gc, unsigned int offset)
struct ftdi_private *priv = usb_get_serial_port_data(port);
int result;
- if (priv->gpio_altfunc & BIT(offset))
- return -ENODEV;
-
mutex_lock(&priv->gpio_lock);
if (!priv->gpio_used) {
/* Set default pin states, as we cannot get them from device */
@@ -2002,6 +1999,25 @@ static int ftdi_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio,
return result;
}
+static int ftdi_gpio_init_valid_mask(struct gpio_chip *gc,
+ unsigned long *valid_mask,
+ unsigned int ngpios)
+{
+ struct usb_serial_port *port = gpiochip_get_data(gc);
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ unsigned long map = priv->gpio_altfunc;
+
+ bitmap_complement(valid_mask, &map, ngpios);
+
+ if (bitmap_empty(valid_mask, ngpios))
+ dev_dbg(&port->dev, "no CBUS pin configured for GPIO\n");
+ else
+ dev_dbg(&port->dev, "CBUS%*pbl configured for GPIO\n", ngpios,
+ valid_mask);
+
+ return 0;
+}
+
static int ftdi_read_eeprom(struct usb_serial *serial, void *dst, u16 addr,
u16 nbytes)
{
@@ -2173,6 +2189,7 @@ static int ftdi_gpio_init(struct usb_serial_port *port)
priv->gc.get_direction = ftdi_gpio_direction_get;
priv->gc.direction_input = ftdi_gpio_direction_input;
priv->gc.direction_output = ftdi_gpio_direction_output;
+ priv->gc.init_valid_mask = ftdi_gpio_init_valid_mask;
priv->gc.get = ftdi_gpio_get;
priv->gc.set = ftdi_gpio_set;
priv->gc.get_multiple = ftdi_gpio_get_multiple;