[bug report] tty: st-asc: switch to using devm_gpiod_get()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Dmitry Torokhov,

The patch 8c44f9b566a3: "tty: st-asc: switch to using
devm_gpiod_get()" from Jan 4, 2020, leads to the following Smatch
static checker warning:

	drivers/gpio/gpiolib-devres.c:118 devm_gpiod_get_index()
	warn: sleeping in atomic context

The call tree is:

asc_set_termios() <- disables preempt (spin_lock)
-> devm_gpiod_get()
   -> devm_gpiod_get_index()

drivers/tty/serial/st-asc.c
   502  static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
   503                              const struct ktermios *old)
   504  {
   505          struct asc_port *ascport = to_asc_port(port);
   506          struct gpio_desc *gpiod;
   507          unsigned int baud;
   508          u32 ctrl_val;
   509          tcflag_t cflag;
   510          unsigned long flags;
   511  
   512          /* Update termios to reflect hardware capabilities */
   513          termios->c_cflag &= ~(CMSPAR |
   514                           (ascport->hw_flow_control ? 0 : CRTSCTS));
   515  
   516          port->uartclk = clk_get_rate(ascport->clk);
   517  
   518          baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
   519          cflag = termios->c_cflag;
   520  
   521          spin_lock_irqsave(&port->lock, flags);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
disables preempt

   522  
   523          /* read control register */
   524          ctrl_val = asc_in(port, ASC_CTL);
   525  
   526          /* stop serial port and reset value */
   527          asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));
   528          ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;
   529  
   530          /* reset fifo rx & tx */
   531          asc_out(port, ASC_TXRESET, 1);
   532          asc_out(port, ASC_RXRESET, 1);
   533  
   534          /* set character length */
   535          if ((cflag & CSIZE) == CS7) {
   536                  ctrl_val |= ASC_CTL_MODE_7BIT_PAR;
   537                  cflag |= PARENB;
   538          } else {
   539                  ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :
   540                                                  ASC_CTL_MODE_8BIT;
   541                  cflag &= ~CSIZE;
   542                  cflag |= CS8;
   543          }
   544          termios->c_cflag = cflag;
   545  
   546          /* set stop bit */
   547          ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;
   548  
   549          /* odd parity */
   550          if (cflag & PARODD)
   551                  ctrl_val |= ASC_CTL_PARITYODD;
   552  
   553          /* hardware flow control */
   554          if ((cflag & CRTSCTS)) {
   555                  ctrl_val |= ASC_CTL_CTSENABLE;
   556  
   557                  /* If flow-control selected, stop handling RTS manually */
   558                  if (ascport->rts) {
   559                          devm_gpiod_put(port->dev, ascport->rts);
   560                          ascport->rts = NULL;
   561  
   562                          pinctrl_select_state(ascport->pinctrl,
   563                                               ascport->states[DEFAULT]);
   564                  }
   565          } else {
   566                  /* If flow-control disabled, it's safe to handle RTS manually */
   567                  if (!ascport->rts && ascport->states[NO_HW_FLOWCTRL]) {
   568                          pinctrl_select_state(ascport->pinctrl,
   569                                               ascport->states[NO_HW_FLOWCTRL]);
   570  
   571                          gpiod = devm_gpiod_get(port->dev, "rts", GPIOD_OUT_LOW);
                                        ^^^^^^^^^^^^^^
Sleeps


   572                          if (!IS_ERR(gpiod)) {
   573                                  gpiod_set_consumer_name(gpiod,
   574                                                  port->dev->of_node->name);
   575                                  ascport->rts = gpiod;
   576                          }
   577                  }
   578          }
   579  
   580          if ((baud < 19200) && !ascport->force_m1) {
   581                  asc_out(port, ASC_BAUDRATE, (port->uartclk / (16 * baud)));
   582          } else {
   583                  /*
   584                   * MODE 1: recommended for high bit rates (above 19.2K)

[ snip ]

drivers/gpio/gpiolib-devres.c
    108          */
    109         if (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
    110                 struct devres *dres;
    111 
    112                 dres = devres_find(dev, devm_gpiod_release,
    113                                    devm_gpiod_match, &desc);
    114                 if (dres)
    115                         return desc;
    116         }
    117 
--> 118         dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
    119                           GFP_KERNEL);
                                  ^^^^^^^^^^
Sleeping here.

    120         if (!dr) {
    121                 gpiod_put(desc);
    122                 return ERR_PTR(-ENOMEM);
    123         }
    124 
    125         *dr = desc;
    126         devres_add(dev, dr);
    127 
    128         return desc;
    129 }

regards,
dan carpenter



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux