mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
Merge branch 'staging/kernel-msm/MMI-U1UGS34.23-110-23-2' into lineage-22.2
Based on tag 'MMI-U1UGS34.23-110-23-2' of https://github.com/MotorolaMobilityLLC/kernel-msm "Fogos push for Android 14" * staging/kernel-msm/MMI-U1UGS34.23-110-23-2: (698 commits) mmc: sdhci-msm: Move MMC_CAP2_MAX_DISCARD_SIZE to prevent merge conflict Reapply "UPSTREAM: binder: fix the missing BR_FROZEN_REPLY in binder_return_strings" Revert "qseecom: Suppress suspend warning if without bus scaling." Revert "Penang: fix for device suspend tests fail. [1/2]" Revert "Penang: resolve kasan panic" Revert "Penang: kasan panic" Revert "penang: device suspend tests fail" Revert "net: qrtr: get svc_id before queueing sk_buff" Revert "af_unix: Do not use atomic ops for unix_sk(sk)->inflight." Revert "af_unix: Fix garbage collector racing against connect()" Revert "BACKPORT: net: fix __dst_negative_advice() race" Revert "ANDROID: ABI fixup for abi break in struct dst_ops" Revert "BACKPORT:sched: Provide sched_set_fifo()" Revert "msm: npu: Fix use after free issue" Revert "fs:EROFS:Porting 5.10 erofs to 5.4" Revert "BACKPORT:erofs: add per-cpu threads for decompression as an option" Revert "UPSTREAM: erofs: fix an error code in z_erofs_init_zip_subsystem()" msm: adsprpc: Avoid taking reference for group_info adsprpc: Handle UAF scenario in put_args msm: adsprpc: use-after-free (UAF) in global maps ... Change-Id: Ia48438f247670d77560472205994632fa62062dd
This commit is contained in:
commit
869b1e64a6
229 changed files with 20042 additions and 329 deletions
|
|
@ -145,6 +145,14 @@ config I2C_DEBUG_BUS
|
|||
a problem with I2C support and want to see more of what is going
|
||||
on.
|
||||
|
||||
config QCOM_I2C_NACK_ERR_WA
|
||||
bool "I2C Bus nack err for fac"
|
||||
default 'n'
|
||||
help
|
||||
Say Y here if you want the I2C bus drivers to produce a bunch of
|
||||
debug messages to the system log. Select this if you are having
|
||||
a problem with I2C support and want to see more of what is going
|
||||
on.
|
||||
endif # I2C
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@
|
|||
|
||||
#define MAX_SE 20
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_I2C_NACK_ERR_WA)
|
||||
u8 i2c_wt6670_dl_mode = 0;
|
||||
#endif
|
||||
|
||||
enum i2c_se_mode {
|
||||
UNINITIALIZED,
|
||||
FIFO_SE_DMA,
|
||||
|
|
@ -135,7 +139,6 @@ struct geni_i2c_dev {
|
|||
bool first_resume;
|
||||
bool gpi_reset;
|
||||
bool disable_dma_mode;
|
||||
bool prev_cancel_pending; //Halt cancel till IOS in good state
|
||||
bool is_i2c_rtl_based; /* doing pending cancel only for rtl based SE's */
|
||||
atomic_t is_xfer_in_progress; /* Used to maintain xfer inprogress status */
|
||||
};
|
||||
|
|
@ -246,58 +249,6 @@ err_ret:
|
|||
gi2c->err = gi2c_log[err].err;
|
||||
}
|
||||
|
||||
static int do_pending_cancel(struct geni_i2c_dev *gi2c)
|
||||
{
|
||||
int timeout = 0;
|
||||
u32 geni_ios = 0;
|
||||
|
||||
/* doing pending cancel only rtl based SE's */
|
||||
if (!gi2c->is_i2c_rtl_based)
|
||||
return 0;
|
||||
|
||||
geni_ios = geni_read_reg_nolog(gi2c->base, SE_GENI_IOS);
|
||||
if ((geni_ios & 0x3) != 0x3) {
|
||||
/* Try to restore IOS with FORCE_DEFAULT */
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"%s: IOS:0x%x, bad state\n", __func__, geni_ios);
|
||||
|
||||
geni_write_reg(FORCE_DEFAULT,
|
||||
gi2c->base, GENI_FORCE_DEFAULT_REG);
|
||||
geni_ios = geni_read_reg_nolog(gi2c->base, SE_GENI_IOS);
|
||||
if ((geni_ios & 0x3) != 0x3) {
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"%s: IOS:0x%x, Fix from Slave side\n",
|
||||
__func__, geni_ios);
|
||||
return -EINVAL;
|
||||
}
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"%s: IOS:0x%x restored properly\n", __func__, geni_ios);
|
||||
}
|
||||
|
||||
if (gi2c->se_mode == GSI_ONLY) {
|
||||
dmaengine_terminate_all(gi2c->tx_c);
|
||||
gi2c->cfg_sent = 0;
|
||||
} else {
|
||||
reinit_completion(&gi2c->xfer);
|
||||
geni_cancel_m_cmd(gi2c->base);
|
||||
timeout = wait_for_completion_timeout(&gi2c->xfer, HZ);
|
||||
if (!timeout) {
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"%s:Pending Cancel failed\n", __func__);
|
||||
reinit_completion(&gi2c->xfer);
|
||||
geni_abort_m_cmd(gi2c->base);
|
||||
timeout = wait_for_completion_timeout(&gi2c->xfer, HZ);
|
||||
if (!timeout)
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"%s:Abort failed\n", __func__);
|
||||
}
|
||||
}
|
||||
gi2c->prev_cancel_pending = false;
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"%s: Pending Cancel done\n", __func__);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
static int geni_i2c_prepare(struct geni_i2c_dev *gi2c)
|
||||
{
|
||||
if (gi2c->se_mode == UNINITIALIZED) {
|
||||
|
|
@ -346,6 +297,15 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
|
|||
u32 dma = readl_relaxed(gi2c->base + SE_GENI_DMA_MODE_EN);
|
||||
struct i2c_msg *cur = gi2c->cur;
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_I2C_NACK_ERR_WA)
|
||||
//wt6670 download mode i2c addr
|
||||
if(cur[0].addr == 0x2B){
|
||||
i2c_wt6670_dl_mode = 1;
|
||||
} else if(cur[0].addr == 0x35){
|
||||
i2c_wt6670_dl_mode = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cur) {
|
||||
geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl);
|
||||
GENI_SE_ERR(gi2c->ipcl, false, gi2c->dev, "Spurious irq\n");
|
||||
|
|
@ -358,8 +318,15 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev)
|
|||
(m_stat & M_CMD_ABORT_EN) ||
|
||||
(m_stat & M_GP_IRQ_1_EN)) {
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_I2C_NACK_ERR_WA)
|
||||
if(i2c_wt6670_dl_mode == 0){
|
||||
if (m_stat & M_GP_IRQ_1_EN)
|
||||
geni_i2c_err(gi2c, I2C_NACK);
|
||||
}
|
||||
#else
|
||||
if (m_stat & M_GP_IRQ_1_EN)
|
||||
geni_i2c_err(gi2c, I2C_NACK);
|
||||
#endif
|
||||
if (m_stat & M_GP_IRQ_3_EN)
|
||||
geni_i2c_err(gi2c, I2C_BUS_PROTO);
|
||||
if (m_stat & M_GP_IRQ_4_EN)
|
||||
|
|
@ -994,8 +961,6 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
|
|||
timeout = wait_for_completion_timeout(&gi2c->xfer,
|
||||
gi2c->xfer_timeout);
|
||||
if (!timeout) {
|
||||
u32 geni_ios = 0;
|
||||
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"I2C gsi xfer timeout:%u flags:%d addr:0x%x\n",
|
||||
gi2c->xfer_timeout, gi2c->cur->flags,
|
||||
|
|
@ -1003,18 +968,6 @@ static int geni_i2c_gsi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
|
|||
geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base,
|
||||
gi2c->ipcl);
|
||||
gi2c->err = -ETIMEDOUT;
|
||||
|
||||
/* WAR: Set flag to mark cancel pending if IOS stuck */
|
||||
geni_ios = geni_read_reg_nolog(gi2c->base, SE_GENI_IOS);
|
||||
if ((geni_ios & 0x3) != 0x3) { //SCL:b'1, SDA:b'0
|
||||
GENI_SE_DBG(gi2c->ipcl, true, gi2c->dev,
|
||||
"%s: IO lines not in good state\n", __func__);
|
||||
/* doing pending cancel only rtl based SE's */
|
||||
if (gi2c->is_i2c_rtl_based) {
|
||||
gi2c->prev_cancel_pending = true;
|
||||
goto geni_i2c_gsi_cancel_pending;
|
||||
}
|
||||
}
|
||||
}
|
||||
geni_i2c_err_prep_sg:
|
||||
if (gi2c->err) {
|
||||
|
|
@ -1037,7 +990,6 @@ geni_i2c_err_prep_sg:
|
|||
/* Resend cfg tre for every new message on shared se */
|
||||
gi2c->cfg_sent = 0;
|
||||
|
||||
geni_i2c_gsi_cancel_pending:
|
||||
if (msgs[i].flags & I2C_M_RD)
|
||||
geni_se_iommu_unmap_buf(rx_dev, &gi2c->rx_ph,
|
||||
msgs[i].len, DMA_FROM_DEVICE);
|
||||
|
|
@ -1065,6 +1017,14 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
|
|||
gi2c->err = 0;
|
||||
atomic_set(&gi2c->is_xfer_in_progress, 1);
|
||||
|
||||
#if IS_ENABLED(CONFIG_QCOM_I2C_NACK_ERR_WA)
|
||||
//wt6670 download mode i2c addr
|
||||
if(msgs[0].addr == 0x2B){
|
||||
i2c_wt6670_dl_mode = 1;
|
||||
} else if( msgs[0].addr == 0x35){
|
||||
i2c_wt6670_dl_mode = 0;
|
||||
}
|
||||
#endif
|
||||
/* Client to respect system suspend */
|
||||
if (!pm_runtime_enabled(gi2c->dev)) {
|
||||
GENI_SE_ERR(gi2c->ipcl, false, gi2c->dev,
|
||||
|
|
@ -1086,17 +1046,6 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
|
|||
}
|
||||
}
|
||||
|
||||
// WAR : Complete previous pending cancel cmd
|
||||
if (gi2c->prev_cancel_pending) {
|
||||
ret = do_pending_cancel(gi2c);
|
||||
if (ret) {
|
||||
pm_runtime_mark_last_busy(gi2c->dev);
|
||||
pm_runtime_put_autosuspend(gi2c->dev);
|
||||
atomic_set(&gi2c->is_xfer_in_progress, 0);
|
||||
return ret; //Don't perform xfer is cancel failed
|
||||
}
|
||||
}
|
||||
|
||||
GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
|
||||
"n:%d addr:0x%x\n", num, msgs[0].addr);
|
||||
|
||||
|
|
@ -1214,23 +1163,9 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
|
|||
timeout = wait_for_completion_timeout(&gi2c->xfer,
|
||||
gi2c->xfer_timeout);
|
||||
if (!timeout) {
|
||||
u32 geni_ios = 0;
|
||||
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"I2C xfer timeout: %d\n", gi2c->xfer_timeout);
|
||||
geni_i2c_err(gi2c, GENI_TIMEOUT);
|
||||
|
||||
/* WAR: Set flag to mark cancel pending if IOS bad */
|
||||
geni_ios = geni_read_reg_nolog(gi2c->base, SE_GENI_IOS);
|
||||
if ((geni_ios & 0x3) != 0x3) { //SCL:b'1, SDA:b'0
|
||||
GENI_SE_DBG(gi2c->ipcl, true, gi2c->dev,
|
||||
"%s: IO lines not in good state\n", __func__);
|
||||
/* doing pending cancel only rtl based SE's */
|
||||
if (gi2c->is_i2c_rtl_based) {
|
||||
gi2c->prev_cancel_pending = true;
|
||||
goto geni_i2c_txn_ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gi2c->err) {
|
||||
|
|
@ -1272,6 +1207,15 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
|
|||
if (gi2c->err) {
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
|
||||
"i2c error :%d\n", gi2c->err);
|
||||
#if IS_ENABLED(CONFIG_QCOM_I2C_NACK_ERR_WA)
|
||||
if(i2c_wt6670_dl_mode == 1){
|
||||
if(gi2c->err == gi2c_log[I2C_NACK].err) {
|
||||
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,"wt6670 nack continue! :%d\n", gi2c->err);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#define SE_I2C_TX_TRANS_LEN 0x26c
|
||||
#define SE_I2C_RX_TRANS_LEN 0x270
|
||||
#define SE_I2C_SCL_COUNTERS 0x278
|
||||
#define SE_I2C_NOISE_CANCEL_CTL (0x234)
|
||||
|
||||
#define SE_I2C_ERR (M_CMD_OVERRUN_EN | M_ILLEGAL_CMD_EN | M_CMD_FAILURE_EN |\
|
||||
M_GP_IRQ_1_EN | M_GP_IRQ_3_EN | M_GP_IRQ_4_EN)
|
||||
|
|
@ -90,6 +91,8 @@ struct geni_i2c_dev {
|
|||
void *dma_buf;
|
||||
size_t xfer_len;
|
||||
dma_addr_t dma_addr;
|
||||
u32 noise_rjct_scl;
|
||||
u32 noise_rjct_sda;
|
||||
};
|
||||
|
||||
struct geni_i2c_err_log {
|
||||
|
|
@ -164,6 +167,9 @@ static void qcom_geni_i2c_conf(struct geni_i2c_dev *gi2c)
|
|||
val |= itr->t_low_cnt << LOW_COUNTER_SHFT;
|
||||
val |= itr->t_cycle_cnt;
|
||||
writel_relaxed(val, gi2c->se.base + SE_I2C_SCL_COUNTERS);
|
||||
if (gi2c->noise_rjct_scl || gi2c->noise_rjct_sda)
|
||||
geni_write_reg(gi2c->noise_rjct_scl << 1 |
|
||||
gi2c->noise_rjct_sda << 3, gi2c->base, SE_I2C_NOISE_CANCEL_CTL);
|
||||
}
|
||||
|
||||
static void geni_i2c_err_misc(struct geni_i2c_dev *gi2c)
|
||||
|
|
@ -556,6 +562,14 @@ static int geni_i2c_probe(struct platform_device *pdev)
|
|||
if (has_acpi_companion(dev))
|
||||
ACPI_COMPANION_SET(&gi2c->adap.dev, ACPI_COMPANION(dev));
|
||||
|
||||
gi2c->noise_rjct_scl = 0;
|
||||
gi2c->noise_rjct_sda = 0;
|
||||
|
||||
of_property_read_u32(pdev->dev.of_node, "qcom,noise-rjct-scl",
|
||||
&gi2c->noise_rjct_scl);
|
||||
of_property_read_u32(pdev->dev.of_node, "qcom,noise-rjct-sda",
|
||||
&gi2c->noise_rjct_sda);
|
||||
|
||||
gi2c->irq = platform_get_irq(pdev, 0);
|
||||
if (gi2c->irq < 0)
|
||||
return gi2c->irq;
|
||||
|
|
|
|||
Loading…
Reference in a new issue