Skip to content

Commit 7c1bda0

Browse files
committed
Merge tag 'samsung-fixes-6.15' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into arm/fixes
Samsung SoC driver fixes for v6.15 1. Exynos ACPM driver (used on Google GS101): Fix timeout due to missing responses from the firmware part. 2. Samsung USI (serial engines) driver: Correct ineffective unconfiguring of the interface during probe removal. * tag 'samsung-fixes-6.15' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux: soc: samsung: usi: prevent wrong bits inversion during unconfiguring firmware: exynos-acpm: check saved RX before bailing out on empty RX queue Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnd Bergmann <[email protected]>
2 parents 15eaaa7 + dd303e0 commit 7c1bda0

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

drivers/firmware/samsung/exynos-acpm.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,29 @@ struct acpm_match_data {
184184
#define client_to_acpm_chan(c) container_of(c, struct acpm_chan, cl)
185185
#define handle_to_acpm_info(h) container_of(h, struct acpm_info, handle)
186186

187+
/**
188+
* acpm_get_saved_rx() - get the response if it was already saved.
189+
* @achan: ACPM channel info.
190+
* @xfer: reference to the transfer to get response for.
191+
* @tx_seqnum: xfer TX sequence number.
192+
*/
193+
static void acpm_get_saved_rx(struct acpm_chan *achan,
194+
const struct acpm_xfer *xfer, u32 tx_seqnum)
195+
{
196+
const struct acpm_rx_data *rx_data = &achan->rx_data[tx_seqnum - 1];
197+
u32 rx_seqnum;
198+
199+
if (!rx_data->response)
200+
return;
201+
202+
rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]);
203+
204+
if (rx_seqnum == tx_seqnum) {
205+
memcpy(xfer->rxd, rx_data->cmd, xfer->rxlen);
206+
clear_bit(rx_seqnum - 1, achan->bitmap_seqnum);
207+
}
208+
}
209+
187210
/**
188211
* acpm_get_rx() - get response from RX queue.
189212
* @achan: ACPM channel info.
@@ -204,15 +227,16 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
204227
rx_front = readl(achan->rx.front);
205228
i = readl(achan->rx.rear);
206229

207-
/* Bail out if RX is empty. */
208-
if (i == rx_front)
230+
tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, xfer->txd[0]);
231+
232+
if (i == rx_front) {
233+
acpm_get_saved_rx(achan, xfer, tx_seqnum);
209234
return 0;
235+
}
210236

211237
base = achan->rx.base;
212238
mlen = achan->mlen;
213239

214-
tx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, xfer->txd[0]);
215-
216240
/* Drain RX queue. */
217241
do {
218242
/* Read RX seqnum. */
@@ -259,16 +283,8 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
259283
* If the response was not in this iteration of the queue, check if the
260284
* RX data was previously saved.
261285
*/
262-
rx_data = &achan->rx_data[tx_seqnum - 1];
263-
if (!rx_set && rx_data->response) {
264-
rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM,
265-
rx_data->cmd[0]);
266-
267-
if (rx_seqnum == tx_seqnum) {
268-
memcpy(xfer->rxd, rx_data->cmd, xfer->rxlen);
269-
clear_bit(rx_seqnum - 1, achan->bitmap_seqnum);
270-
}
271-
}
286+
if (!rx_set)
287+
acpm_get_saved_rx(achan, xfer, tx_seqnum);
272288

273289
return 0;
274290
}

drivers/soc/samsung/exynos-usi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static void exynos_usi_unconfigure(void *data)
233233
/* Make sure that we've stopped providing the clock to USI IP */
234234
val = readl(usi->regs + USI_OPTION);
235235
val &= ~USI_OPTION_CLKREQ_ON;
236-
val |= ~USI_OPTION_CLKSTOP_ON;
236+
val |= USI_OPTION_CLKSTOP_ON;
237237
writel(val, usi->regs + USI_OPTION);
238238

239239
/* Set USI block state to reset */

0 commit comments

Comments
 (0)