lkml.org 
[lkml]   [2021]   [Apr]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH v6] USB: serial: cp210x: Add support for GPIOs on CP2108
Hi Pho,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on usb-serial/usb-next]
[also build test WARNING on usb/usb-testing tty/tty-testing v5.12-rc6 next-20210401]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Pho-Tran/USB-serial-cp210x-Add-support-for-GPIOs-on-CP2108/20210405-141927
base: https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git usb-next
config: x86_64-randconfig-s022-20210405 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.3-279-g6d5d9b42-dirty
# https://github.com/0day-ci/linux/commit/a4658078c55d4396be894b30d3b94fd86b770f45
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Pho-Tran/USB-serial-cp210x-Add-support-for-GPIOs-on-CP2108/20210405-141927
git checkout a4658078c55d4396be894b30d3b94fd86b770f45
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> drivers/usb/serial/cp210x.c:1540:13: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [addressable] [usertype] buf @@ got unsigned short [usertype] @@
drivers/usb/serial/cp210x.c:1540:13: sparse: expected restricted __le16 [addressable] [usertype] buf
drivers/usb/serial/cp210x.c:1540:13: sparse: got unsigned short [usertype]
>> drivers/usb/serial/cp210x.c:1542:19: sparse: sparse: restricted __le16 degrades to integer
>> drivers/usb/serial/cp210x.c:1581:24: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] wIndex @@ got int @@
drivers/usb/serial/cp210x.c:1581:24: sparse: expected restricted __le16 [usertype] wIndex
drivers/usb/serial/cp210x.c:1581:24: sparse: got int
>> drivers/usb/serial/cp210x.c:1587:57: sparse: sparse: incorrect type in argument 6 (different base types) @@ expected unsigned short [usertype] index @@ got restricted __le16 [usertype] wIndex @@
drivers/usb/serial/cp210x.c:1587:57: sparse: expected unsigned short [usertype] index
drivers/usb/serial/cp210x.c:1587:57: sparse: got restricted __le16 [usertype] wIndex
>> drivers/usb/serial/cp210x.c:1676:14: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] temp @@ got unsigned short [usertype] @@
drivers/usb/serial/cp210x.c:1676:14: sparse: expected restricted __le16 [usertype] temp
drivers/usb/serial/cp210x.c:1676:14: sparse: got unsigned short [usertype]
drivers/usb/serial/cp210x.c:1677:32: sparse: sparse: restricted __le16 degrades to integer
drivers/usb/serial/cp210x.c:1678:14: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] temp @@ got unsigned short [usertype] @@
drivers/usb/serial/cp210x.c:1678:14: sparse: expected restricted __le16 [usertype] temp
drivers/usb/serial/cp210x.c:1678:14: sparse: got unsigned short [usertype]
drivers/usb/serial/cp210x.c:1679:23: sparse: sparse: restricted __le16 degrades to integer
>> drivers/usb/serial/cp210x.c:1679:20: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] gpio_latch @@ got unsigned long @@
drivers/usb/serial/cp210x.c:1679:20: sparse: expected restricted __le16 [usertype] gpio_latch
drivers/usb/serial/cp210x.c:1679:20: sparse: got unsigned long
drivers/usb/serial/cp210x.c:1721:57: sparse: sparse: restricted __le16 degrades to integer

vim +1540 drivers/usb/serial/cp210x.c

1496
1497 static int cp210x_gpio_get(struct gpio_chip *gc, unsigned int gpio)
1498 {
1499 struct usb_serial *serial = gpiochip_get_data(gc);
1500 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
1501 u8 req_type = REQTYPE_DEVICE_TO_HOST;
1502 int result;
1503 __le16 buf;
1504
1505 result = usb_autopm_get_interface(serial->interface);
1506 if (result)
1507 return result;
1508 /*
1509 * This function will be read latch value of gpio and storage to buf(16bit)
1510 * where bit 0 is GPIO0, bit 1 is GPIO1, etc. Up to GPIOn where n is
1511 * total number of GPIO pins the interface supports.
1512 * Interfaces on CP2102N supports 7 GPIOs
1513 * Interfaces on CP2103 amd CP2104 supports 4 GPIOs
1514 * Enhanced interfaces on CP2105 support 3 GPIOs
1515 * Standard interfaces on CP2105 support 4 GPIOs
1516 * Interfaces on CP2108 supports 16 GPIOs
1517 */
1518 switch (priv->partnum) {
1519 /*
1520 * Request type to Read_Latch of CP2105 and Cp2108
1521 * is 0xc1 <REQTYPE_INTERFACE_TO_HOST>
1522 */
1523 case CP210X_PARTNUM_CP2108:
1524 req_type = REQTYPE_INTERFACE_TO_HOST;
1525 result = cp210x_read_vendor_block(serial, req_type,
1526 CP210X_READ_LATCH, &buf, sizeof(__le16));
1527 break;
1528 case CP210X_PARTNUM_CP2105:
1529 req_type = REQTYPE_INTERFACE_TO_HOST;
1530 result = cp210x_read_vendor_block(serial, req_type,
1531 CP210X_READ_LATCH, &buf, sizeof(u8));
1532 break;
1533 default:
1534 result = cp210x_read_vendor_block(serial, req_type,
1535 CP210X_READ_LATCH, &buf, sizeof(u8));
1536 break;
1537 }
1538 if (result < 0)
1539 return result;
> 1540 buf = le16_to_cpu(buf);
1541 usb_autopm_put_interface(serial->interface);
> 1542 return !!(buf & BIT(gpio));
1543 }
1544
1545 static void cp210x_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value)
1546 {
1547 struct usb_serial *serial = gpiochip_get_data(gc);
1548 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
1549 struct cp210x_gpio_write buf;
1550 __le16 wIndex;
1551 int result;
1552
1553 if (value == 1) {
1554 buf.cp210x_8gpios.state = BIT(gpio);
1555 buf.cp210x_16gpios.state = cpu_to_le16(BIT(gpio));
1556 } else {
1557 buf.cp210x_8gpios.state = 0;
1558 buf.cp210x_16gpios.state = 0;
1559 }
1560 buf.cp210x_8gpios.mask = BIT(gpio);
1561 buf.cp210x_16gpios.mask = cpu_to_le16(BIT(gpio));
1562
1563 result = usb_autopm_get_interface(serial->interface);
1564 if (result)
1565 goto out;
1566
1567 switch (priv->partnum) {
1568 case CP210X_PARTNUM_CP2108:
1569 result = cp210x_write_vendor_block(serial,
1570 REQTYPE_HOST_TO_INTERFACE,
1571 CP210X_WRITE_LATCH, &buf.cp210x_16gpios,
1572 sizeof(buf.cp210x_16gpios));
1573 break;
1574 case CP210X_PARTNUM_CP2105:
1575 result = cp210x_write_vendor_block(serial,
1576 REQTYPE_HOST_TO_INTERFACE,
1577 CP210X_WRITE_LATCH, &buf.cp210x_8gpios,
1578 sizeof(buf.cp210x_8gpios));
1579 break;
1580 default:
> 1581 wIndex = buf.cp210x_8gpios.state << 8 | buf.cp210x_8gpios.mask;
1582 result = usb_control_msg(serial->dev,
1583 usb_sndctrlpipe(serial->dev, 0),
1584 CP210X_VENDOR_SPECIFIC,
1585 REQTYPE_HOST_TO_DEVICE,
1586 CP210X_WRITE_LATCH,
> 1587 wIndex,
1588 NULL, 0, USB_CTRL_SET_TIMEOUT);
1589 break;
1590 }
1591 usb_autopm_put_interface(serial->interface);
1592
1593 out:
1594 if (result < 0) {
1595 dev_err(&serial->interface->dev, "failed to set GPIO value: %d\n",
1596 result);
1597 }
1598 }
1599
1600 static int cp210x_gpio_direction_get(struct gpio_chip *gc, unsigned int gpio)
1601 {
1602 struct usb_serial *serial = gpiochip_get_data(gc);
1603 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
1604
1605 return priv->gpio_input & BIT(gpio);
1606 }
1607
1608 static int cp210x_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio)
1609 {
1610 struct usb_serial *serial = gpiochip_get_data(gc);
1611 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
1612
1613 if (priv->partnum == CP210X_PARTNUM_CP2105) {
1614 /* hardware does not support an input mode */
1615 return -ENOTSUPP;
1616 }
1617
1618 /* push-pull pins cannot be changed to be inputs */
1619 if (priv->gpio_pushpull & BIT(gpio))
1620 return -EINVAL;
1621
1622 /* make sure to release pin if it is being driven low */
1623 cp210x_gpio_set(gc, gpio, 1);
1624
1625 priv->gpio_input |= BIT(gpio);
1626
1627 return 0;
1628 }
1629
1630 static int cp210x_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio,
1631 int value)
1632 {
1633 struct usb_serial *serial = gpiochip_get_data(gc);
1634 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
1635
1636 priv->gpio_input &= ~BIT(gpio);
1637 cp210x_gpio_set(gc, gpio, value);
1638
1639 return 0;
1640 }
1641
1642 static int cp210x_gpio_set_config(struct gpio_chip *gc, unsigned int gpio,
1643 unsigned long config)
1644 {
1645 struct usb_serial *serial = gpiochip_get_data(gc);
1646 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
1647 enum pin_config_param param = pinconf_to_config_param(config);
1648
1649 /* Succeed only if in correct mode (this can't be set at runtime) */
1650 if ((param == PIN_CONFIG_DRIVE_PUSH_PULL) &&
1651 (priv->gpio_pushpull & BIT(gpio)))
1652 return 0;
1653
1654 if ((param == PIN_CONFIG_DRIVE_OPEN_DRAIN) &&
1655 !(priv->gpio_pushpull & BIT(gpio)))
1656 return 0;
1657
1658 return -ENOTSUPP;
1659 }
1660
1661 static int cp2108_gpio_init(struct usb_serial *serial)
1662 {
1663 struct cp210x_serial_private *priv = usb_get_serial_data(serial);
1664 struct cp210x_quad_port_config config;
1665 __le16 gpio_latch;
1666 __le16 temp;
1667 int result;
1668 u8 i;
1669
1670 result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST,
1671 CP210X_GET_PORTCONFIG, &config,
1672 sizeof(config));
1673 if (result < 0)
1674 return result;
1675 priv->gc.ngpio = 16;
> 1676 temp = le16_to_cpu(config.reset_state.gpio_mode_PB1);
1677 priv->gpio_pushpull = (temp & CP2108_GPIO_MODE_MASK) >> CP2108_GPIO_MODE_OFFSET;
1678 temp = le16_to_cpu(config.reset_state.gpio_latch_PB1);
> 1679 gpio_latch = (temp & CP2108_GPIO_MODE_MASK) >> CP2108_GPIO_MODE_OFFSET;
1680 /*
1681 * Mark all pins which are not in GPIO mode
1682 * Refer to table 9.1: GPIO Mode alternate Functions on CP2108 datasheet:
1683 * https://www.silabs.com/documents/public/data-sheets/cp2108-datasheet.pdf
1684 * Alternate Functions of GPIO0 to GPIO3 is determine by enhancedfxn_IFC[0]
1685 * and the same for other pins, enhancedfxn_IFC[1]: GPIO4 to GPIO7,
1686 * enhancedfxn_IFC[2]: GPIO8 to GPIO11, enhancedfxn_IFC[3]: GPIO12 to GPIO15.
1687 */
1688 for (i = 0; i < 4; i++) {
1689 switch (config.enhancedfxn_IFC[i]) {
1690 case EF_IFC_GPIO_TXLED:
1691 priv->gpio_altfunc |= BIT(i * 4);
1692 break;
1693 case EF_IFC_GPIO_RXLED:
1694 priv->gpio_altfunc |= BIT((i * 4) + 1);
1695 break;
1696 case EF_IFC_GPIO_RS485_LOGIC:
1697 case EF_IFC_GPIO_RS485:
1698 priv->gpio_altfunc |= BIT((i * 4) + 2);
1699 break;
1700 case EF_IFC_GPIO_CLOCK:
1701 priv->gpio_altfunc |= BIT((i * 4) + 3);
1702 break;
1703 case EF_IFC_DYNAMIC_SUSPEND:
1704 priv->gpio_altfunc |= BIT(i * 4);
1705 priv->gpio_altfunc |= BIT((i * 4) + 1);
1706 priv->gpio_altfunc |= BIT((i * 4) + 2);
1707 priv->gpio_altfunc |= BIT((i * 4) + 3);
1708 break;
1709 }
1710 }
1711 /*
1712 * Like CP2102N, CP2108 has also no strict input and output pin
1713 * modes.
1714 * Do the same input mode emulation as CP2102N.
1715 */
1716 for (i = 0; i < priv->gc.ngpio; ++i) {
1717 /*
1718 * Set direction to "input" iff pin is open-drain and reset
1719 * value is 1.
1720 */
1721 if (!(priv->gpio_pushpull & BIT(i)) && (gpio_latch & BIT(i)))
1722 priv->gpio_input |= BIT(i);
1723 }
1724
1725 return 0;
1726 }
1727

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[unhandled content-type:application/gzip]
\
 
 \ /
  Last update: 2021-04-05 11:25    [W:0.155 / U:0.412 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site