static int wm8961_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8961_priv *wm8961; unsigned int val; int ret; wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv), GFP_KERNEL); if (wm8961 == NULL) return -ENOMEM; wm8961->regmap = devm_regmap_init_i2c(i2c, &wm8961_regmap); if (IS_ERR(wm8961->regmap)) return PTR_ERR(wm8961->regmap); ret = regmap_read(wm8961->regmap, WM8961_SOFTWARE_RESET, &val); if (ret != 0) { dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); return ret; } if (val != 0x1801) { dev_err(&i2c->dev, "Device is not a WM8961: ID=0x%x\n", val); return -EINVAL; } /* This isn't volatile - readback doesn't correspond to write */ regcache_cache_bypass(wm8961->regmap, true); ret = regmap_read(wm8961->regmap, WM8961_RIGHT_INPUT_VOLUME, &val); regcache_cache_bypass(wm8961->regmap, false); if (ret != 0) { dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret); return ret; } dev_info(&i2c->dev, "WM8961 family %d revision %c\n", (val & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, ((val & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) + 'A'); ret = regmap_write(wm8961->regmap, WM8961_SOFTWARE_RESET, 0x1801); if (ret != 0) { dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); return ret; } i2c_set_clientdata(i2c, wm8961); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8961, &wm8961_dai, 1); return ret; }
static int sc16is7xx_startup(struct uart_port *port) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); unsigned int val; sc16is7xx_power(port, 1); /* Reset FIFOs*/ val = SC16IS7XX_FCR_RXRESET_BIT | SC16IS7XX_FCR_TXRESET_BIT; sc16is7xx_port_write(port, SC16IS7XX_FCR_REG, val); udelay(5); sc16is7xx_port_write(port, SC16IS7XX_FCR_REG, SC16IS7XX_FCR_FIFO_BIT); /* Enable EFR */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_B); regcache_cache_bypass(s->regmap, true); /* Enable write access to enhanced features and internal clock div */ sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, SC16IS7XX_EFR_ENABLE_BIT); /* Enable TCR/TLR */ sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, SC16IS7XX_MCR_TCRTLR_BIT, SC16IS7XX_MCR_TCRTLR_BIT); /* Configure flow control levels */ /* Flow control halt level 48, resume level 24 */ sc16is7xx_port_write(port, SC16IS7XX_TCR_REG, SC16IS7XX_TCR_RX_RESUME(24) | SC16IS7XX_TCR_RX_HALT(48)); regcache_cache_bypass(s->regmap, false); /* Now, initialize the UART */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8); /* Enable the Rx and Tx FIFO */ sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, SC16IS7XX_EFCR_RXDISABLE_BIT | SC16IS7XX_EFCR_TXDISABLE_BIT, 0); /* Enable RX, TX, CTS change interrupts */ val = SC16IS7XX_IER_RDI_BIT | SC16IS7XX_IER_THRI_BIT | SC16IS7XX_IER_CTSI_BIT; sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); return 0; }
static int sc16is7xx_set_baud(struct uart_port *port, int baud) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); u8 lcr; u8 prescaler = 0; unsigned long clk = port->uartclk, div = clk / 16 / baud; if (div > 0xffff) { prescaler = SC16IS7XX_MCR_CLKSEL_BIT; div /= 4; } lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG); /* Open the LCR divisors for configuration */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_B); /* Enable enhanced features */ regcache_cache_bypass(s->regmap, true); sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, SC16IS7XX_EFR_ENABLE_BIT); regcache_cache_bypass(s->regmap, false); /* Put LCR back to the normal mode */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, SC16IS7XX_MCR_CLKSEL_BIT, prescaler); /* Open the LCR divisors for configuration */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_A); /* Write the new divisor */ regcache_cache_bypass(s->regmap, true); sc16is7xx_port_write(port, SC16IS7XX_DLH_REG, div / 256); sc16is7xx_port_write(port, SC16IS7XX_DLL_REG, div % 256); regcache_cache_bypass(s->regmap, false); /* Put LCR back to the normal mode */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); return DIV_ROUND_CLOSEST(clk / 16, div); }
static int adau1977_reset(struct adau1977 *adau1977) { int ret; /* * The reset bit is obviously volatile, but we need to be able to cache * the other bits in the register, so we can't just mark the whole * register as volatile. Since this is the only place where we'll ever * touch the reset bit just bypass the cache for this operation. */ regcache_cache_bypass(adau1977->regmap, true); ret = regmap_write(adau1977->regmap, ADAU1977_REG_POWER, ADAU1977_POWER_RESET); regcache_cache_bypass(adau1977->regmap, false); if (ret) return ret; return ret; }
/** * twl_regcache_bypass - Configure the regcache bypass for the regmap associated * with the module * @mod_no: module number * @enable: Regcache bypass state * * Returns 0 else failure. */ int twl_set_regcache_bypass(u8 mod_no, bool enable) { struct regmap *regmap = twl_get_regmap(mod_no); if (!regmap) return -EPERM; regcache_cache_bypass(regmap, enable); return 0; }
/* work around ESD issue where sta32x resets and loses all configuration */ static void sta32x_watchdog(struct work_struct *work) { struct sta32x_priv *sta32x = container_of(work, struct sta32x_priv, watchdog_work.work); struct snd_soc_codec *codec = sta32x->codec; unsigned int confa, confa_cached; /* check if sta32x has reset itself */ confa_cached = snd_soc_read(codec, STA32X_CONFA); regcache_cache_bypass(sta32x->regmap, true); confa = snd_soc_read(codec, STA32X_CONFA); regcache_cache_bypass(sta32x->regmap, false); if (confa != confa_cached) { regcache_mark_dirty(sta32x->regmap); sta32x_cache_sync(codec); } if (!sta32x->shutdown) schedule_delayed_work(&sta32x->watchdog_work, round_jiffies_relative(HZ)); }
static void sc16is7xx_handle_tx(struct uart_port *port) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); struct circ_buf *xmit = &port->state->xmit; unsigned int txlen, to_send, i; if (unlikely(port->x_char)) { sc16is7xx_port_write(port, SC16IS7XX_THR_REG, port->x_char); port->icount.tx++; port->x_char = 0; return; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return; /* Get length of data pending in circular buffer */ to_send = uart_circ_chars_pending(xmit); if (likely(to_send)) { /* Limit to size of TX FIFO */ txlen = sc16is7xx_port_read(port, SC16IS7XX_TXLVL_REG); to_send = (to_send > txlen) ? txlen : to_send; /* Add data to send */ port->icount.tx += to_send; /* Convert to linear buffer */ for (i = 0; i < to_send; ++i) { s->buf[i] = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); } regcache_cache_bypass(s->regmap, true); regmap_raw_write(s->regmap, SC16IS7XX_THR_REG, s->buf, to_send); regcache_cache_bypass(s->regmap, false); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); }
static int max97236_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max97236_priv *max97236; int ret; max97236 = kzalloc(sizeof(struct max97236_priv), GFP_KERNEL); if (max97236 == NULL) return -ENOMEM; max97236->devtype = id->driver_data; i2c_set_clientdata(i2c, max97236); max97236->control_data = i2c; max97236->pdata = i2c->dev.platform_data; if (!max97236->pdata && i2c->dev.of_node) max97236->pdata = max97236_of_pdata(i2c); max97236->regmap = regmap_init_i2c(i2c, &max97236_regmap); if (IS_ERR(max97236->regmap)) { ret = PTR_ERR(max97236->regmap); dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); goto err_enable; } regcache_cache_bypass(max97236->regmap, false); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max97236, max97236_dai, ARRAY_SIZE(max97236_dai)); if (ret < 0) regmap_exit(max97236->regmap); err_enable: return ret; }
static int adau1977_power_enable(struct adau1977 *adau1977) { unsigned int val; int ret = 0; if (adau1977->enabled) return 0; ret = regulator_enable(adau1977->avdd_reg); if (ret) return ret; if (adau1977->dvdd_reg) { ret = regulator_enable(adau1977->dvdd_reg); if (ret) goto err_disable_avdd; } if (adau1977->reset_gpio) gpiod_set_value_cansleep(adau1977->reset_gpio, 1); regcache_cache_only(adau1977->regmap, false); if (adau1977->switch_mode) adau1977->switch_mode(adau1977->dev); ret = adau1977_reset(adau1977); if (ret) goto err_disable_dvdd; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER, ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP); if (ret) goto err_disable_dvdd; ret = regcache_sync(adau1977->regmap); if (ret) goto err_disable_dvdd; /* * The PLL register is not affected by the software reset. It is * possible that the value of the register was changed to the * default value while we were in cache only mode. In this case * regcache_sync will skip over it and we have to manually sync * it. */ ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val); if (ret) goto err_disable_dvdd; if (val == 0x41) { regcache_cache_bypass(adau1977->regmap, true); ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL, 0x41); if (ret) goto err_disable_dvdd; regcache_cache_bypass(adau1977->regmap, false); } adau1977->enabled = true; return ret; err_disable_dvdd: if (adau1977->dvdd_reg) regulator_disable(adau1977->dvdd_reg); err_disable_avdd: regulator_disable(adau1977->avdd_reg); return ret; }
static int arizona_apply_hardware_patch(struct arizona* arizona) { unsigned int fll, sysclk; int ret, err; regcache_cache_bypass(arizona->regmap, true); /* Cache existing FLL and SYSCLK settings */ ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &fll); if (ret != 0) { dev_err(arizona->dev, "Failed to cache FLL settings: %d\n", ret); return ret; } ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &sysclk); if (ret != 0) { dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n", ret); return ret; } /* Start up SYSCLK using the FLL in free running mode */ ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN); if (ret != 0) { dev_err(arizona->dev, "Failed to start FLL in freerunning mode: %d\n", ret); return ret; } ret = arizona_poll_reg(arizona, 25, ARIZONA_INTERRUPT_RAW_STATUS_5, ARIZONA_FLL1_CLOCK_OK_STS, ARIZONA_FLL1_CLOCK_OK_STS); if (ret != 0) { dump_stack(); ret = -ETIMEDOUT; goto err_fll; } ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144); if (ret != 0) { dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret); goto err_fll; } /* Start the write sequencer and wait for it to finish */ ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0, ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160); if (ret != 0) { dev_err(arizona->dev, "Failed to start write sequencer: %d\n", ret); goto err_sysclk; } ret = arizona_poll_reg(arizona, 5, ARIZONA_WRITE_SEQUENCER_CTRL_1, ARIZONA_WSEQ_BUSY, 0); if (ret != 0) { regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0, ARIZONA_WSEQ_ABORT); ret = -ETIMEDOUT; } err_sysclk: err = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, sysclk); if (err != 0) { dev_err(arizona->dev, "Failed to re-apply old SYSCLK settings: %d\n", err); } err_fll: err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, fll); if (err != 0) { dev_err(arizona->dev, "Failed to re-apply old FLL settings: %d\n", err); } regcache_cache_bypass(arizona->regmap, false); if (ret != 0) return ret; else return err; }
static int cs42l73_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { struct cs42l73_private *cs42l73; struct cs42l73_platform_data *pdata = dev_get_platdata(&i2c_client->dev); int ret; unsigned int devid = 0; unsigned int reg; u32 val32; cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private), GFP_KERNEL); if (!cs42l73) return -ENOMEM; cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap); if (IS_ERR(cs42l73->regmap)) { ret = PTR_ERR(cs42l73->regmap); dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); return ret; } if (pdata) { cs42l73->pdata = *pdata; } else { pdata = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&i2c_client->dev, "could not allocate pdata\n"); return -ENOMEM; } if (i2c_client->dev.of_node) { if (of_property_read_u32(i2c_client->dev.of_node, "chgfreq", &val32) >= 0) pdata->chgfreq = val32; } pdata->reset_gpio = of_get_named_gpio(i2c_client->dev.of_node, "reset-gpio", 0); cs42l73->pdata = *pdata; } i2c_set_clientdata(i2c_client, cs42l73); if (cs42l73->pdata.reset_gpio) { ret = devm_gpio_request_one(&i2c_client->dev, cs42l73->pdata.reset_gpio, GPIOF_OUT_INIT_HIGH, "CS42L73 /RST"); if (ret < 0) { dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", cs42l73->pdata.reset_gpio, ret); return ret; } gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 0); gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 1); } regcache_cache_bypass(cs42l73->regmap, true); /* initialize codec */ ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); devid = (reg & 0xFF) << 12; ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, ®); devid |= (reg & 0xFF) << 4; ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®); devid |= (reg & 0xF0) >> 4; if (devid != CS42L73_DEVID) { ret = -ENODEV; dev_err(&i2c_client->dev, "CS42L73 Device ID (%X). Expected %X\n", devid, CS42L73_DEVID); return ret; } ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); if (ret < 0) { dev_err(&i2c_client->dev, "Get Revision ID failed\n"); return ret;; } dev_info(&i2c_client->dev, "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF); regcache_cache_bypass(cs42l73->regmap, false); ret = snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_cs42l73, cs42l73_dai, ARRAY_SIZE(cs42l73_dai)); if (ret < 0) return ret; return 0; }
static int max98505_probe(struct snd_soc_codec *codec) { struct max98505_priv *max98505 = snd_soc_codec_get_drvdata(codec); struct max98505_cdata *cdata; int ret = 0; int reg = 0; dev_info(codec->dev, "MONO - built on %s at %s\n", __DATE__, __TIME__); dev_info(codec->dev, "build number %s\n", MAX98505_REVISION); max98505->codec = codec; codec->control_data = max98505->regmap; ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } max98505->sysclk = 12288000; max98505->volume = 0x07; cdata = &max98505->dai[0]; cdata->rate = (unsigned)-1; cdata->fmt = (unsigned)-1; reg = 0; ret = regmap_read(max98505->regmap, MAX98505_R0FF_VERSION, ®); if ((ret < 0) || ((reg != MAX98505_VERSION) && (reg != MAX98505_VERSION1) && (reg != MAX98505_VERSION2))) { dev_err(codec->dev, "device initialization error (%d 0x%02X)\n", ret, reg); goto err_access; } dev_info(codec->dev, "device version 0x%02X\n", reg); #if 0 /* FOR DEBUGGING ONLY */ regcache_cache_bypass(max98505->regmap, true); dev_info(codec->dev, "regmap cache bypass ENABLED!\n"); /**********************/ #endif regmap_write(max98505->regmap, MAX98505_R038_GLOBAL_ENABLE, 0x00); /* It's not the default but we need to set DAI_DLY */ regmap_write(max98505->regmap, MAX98505_R020_FORMAT, M98505_DAI_DLY_MASK); regmap_write(max98505->regmap, MAX98505_R021_TDM_SLOT_SELECT, 0xC8); regmap_write(max98505->regmap, MAX98505_R027_DOUT_HIZ_CFG1, 0xFF); regmap_write(max98505->regmap, MAX98505_R028_DOUT_HIZ_CFG2, 0xFF); regmap_write(max98505->regmap, MAX98505_R029_DOUT_HIZ_CFG3, 0xFF); regmap_write(max98505->regmap, MAX98505_R02A_DOUT_HIZ_CFG4, 0xF0); regmap_write(max98505->regmap, MAX98505_R02C_FILTERS, 0xD8); // regmap_write(max98505->regmap, MAX98505_R034_ALC_CONFIGURATION, 0xF8); regmap_write(max98505->regmap, MAX98505_R034_ALC_CONFIGURATION, 0x12); /*****************************************************************/ /* Set boost output to minimum until DSM is implemented */ regmap_write(max98505->regmap, MAX98505_R037_CONFIGURATION, 0xF0); /*****************************************************************/ // Disable ALC muting regmap_write(max98505->regmap, MAX98505_R03A_BOOST_LIMITER, 0xF8); regmap_update_bits(max98505->regmap, MAX98505_R02D_GAIN, M98505_DAC_IN_SEL_MASK, M98505_DAC_IN_SEL_DIV2_SUMMED_DAI); max98505_handle_pdata(codec); max98505_add_widgets(codec); ret = sysfs_create_group(&codec->dev->kobj, &maxim_attribute_group); if(ret) { pr_err("failed to create sysfs group [%d]", ret); } err_access: pr_info("%s: exit %d\n", __func__, ret); ret = 0; // temp return ret; }
static void sc16is7xx_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); unsigned int lcr, flow = 0; int baud; /* Mask termios capabilities we don't support */ termios->c_cflag &= ~CMSPAR; /* Word size */ switch (termios->c_cflag & CSIZE) { case CS5: lcr = SC16IS7XX_LCR_WORD_LEN_5; break; case CS6: lcr = SC16IS7XX_LCR_WORD_LEN_6; break; case CS7: lcr = SC16IS7XX_LCR_WORD_LEN_7; break; case CS8: lcr = SC16IS7XX_LCR_WORD_LEN_8; break; default: lcr = SC16IS7XX_LCR_WORD_LEN_8; termios->c_cflag &= ~CSIZE; termios->c_cflag |= CS8; break; } /* Parity */ if (termios->c_cflag & PARENB) { lcr |= SC16IS7XX_LCR_PARITY_BIT; if (!(termios->c_cflag & PARODD)) lcr |= SC16IS7XX_LCR_EVENPARITY_BIT; } /* Stop bits */ if (termios->c_cflag & CSTOPB) lcr |= SC16IS7XX_LCR_STOPLEN_BIT; /* 2 stops */ /* Set read status mask */ port->read_status_mask = SC16IS7XX_LSR_OE_BIT; if (termios->c_iflag & INPCK) port->read_status_mask |= SC16IS7XX_LSR_PE_BIT | SC16IS7XX_LSR_FE_BIT; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= SC16IS7XX_LSR_BI_BIT; /* Set status ignore mask */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNBRK) port->ignore_status_mask |= SC16IS7XX_LSR_BI_BIT; if (!(termios->c_cflag & CREAD)) port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK; sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_B); /* Configure flow control */ regcache_cache_bypass(s->regmap, true); sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]); sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]); if (termios->c_cflag & CRTSCTS) flow |= SC16IS7XX_EFR_AUTOCTS_BIT | SC16IS7XX_EFR_AUTORTS_BIT; if (termios->c_iflag & IXON) flow |= SC16IS7XX_EFR_SWFLOW3_BIT; if (termios->c_iflag & IXOFF) flow |= SC16IS7XX_EFR_SWFLOW1_BIT; sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, flow); regcache_cache_bypass(s->regmap, false); /* Update LCR register */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); /* Get baud rate generator configuration */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / 4 / 0xffff, port->uartclk / 16); /* Setup baudrate generator */ baud = sc16is7xx_set_baud(port, baud); /* Update timeout according to new baud rate */ uart_update_timeout(port, termios->c_cflag, baud); }
static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen, unsigned int iir) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); unsigned int lsr = 0, ch, flag, bytes_read, i; bool read_lsr = (iir == SC16IS7XX_IIR_RLSE_SRC) ? true : false; if (unlikely(rxlen >= sizeof(s->buf))) { dev_warn_ratelimited(port->dev, "Port %i: Possible RX FIFO overrun: %d\n", port->line, rxlen); port->icount.buf_overrun++; /* Ensure sanity of RX level */ rxlen = sizeof(s->buf); } while (rxlen) { /* Only read lsr if there are possible errors in FIFO */ if (read_lsr) { lsr = sc16is7xx_port_read(port, SC16IS7XX_LSR_REG); if (!(lsr & SC16IS7XX_LSR_FIFOE_BIT)) read_lsr = false; /* No errors left in FIFO */ } else lsr = 0; if (read_lsr) { s->buf[0] = sc16is7xx_port_read(port, SC16IS7XX_RHR_REG); bytes_read = 1; } else { regcache_cache_bypass(s->regmap, true); regmap_raw_read(s->regmap, SC16IS7XX_RHR_REG, s->buf, rxlen); regcache_cache_bypass(s->regmap, false); bytes_read = rxlen; } lsr &= SC16IS7XX_LSR_BRK_ERROR_MASK; port->icount.rx++; flag = TTY_NORMAL; if (unlikely(lsr)) { if (lsr & SC16IS7XX_LSR_BI_BIT) { port->icount.brk++; if (uart_handle_break(port)) continue; } else if (lsr & SC16IS7XX_LSR_PE_BIT) port->icount.parity++; else if (lsr & SC16IS7XX_LSR_FE_BIT) port->icount.frame++; else if (lsr & SC16IS7XX_LSR_OE_BIT) port->icount.overrun++; lsr &= port->read_status_mask; if (lsr & SC16IS7XX_LSR_BI_BIT) flag = TTY_BREAK; else if (lsr & SC16IS7XX_LSR_PE_BIT) flag = TTY_PARITY; else if (lsr & SC16IS7XX_LSR_FE_BIT) flag = TTY_FRAME; else if (lsr & SC16IS7XX_LSR_OE_BIT) flag = TTY_OVERRUN; } for (i = 0; i < bytes_read; ++i) { ch = s->buf[i]; if (uart_handle_sysrq_char(port, ch)) continue; if (lsr & port->ignore_status_mask) continue; uart_insert_char(port, lsr, SC16IS7XX_LSR_OE_BIT, ch, flag); } rxlen -= bytes_read; } tty_flip_buffer_push(&port->state->port); }