Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dmaengine: stm32-dma3: introduce channel semaphore helpers

Before restoring semaphore status after suspend, introduce new functions
to handle semaphore operations :
- stm32_dma3_get_chan_sem() to take the semaphore
- stm32_dma3_put_chan_sem() to release the semaphore
Also, use a new boolean variable semaphore_taken, which is true when the
semaphore has been taken and false when it has been released.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
Link: https://patch.msgid.link/20251121-dma3_improv-v2-2-76a207b13ea6@foss.st.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Amelie Delaunay and committed by
Vinod Koul
d26eb4a7 0d41ed4e

+44 -11
+44 -11
drivers/dma/stm32/stm32-dma3.c
··· 288 288 u32 fifo_size; 289 289 u32 max_burst; 290 290 bool semaphore_mode; 291 + bool semaphore_taken; 291 292 struct stm32_dma3_dt_conf dt_config; 292 293 struct dma_slave_config dma_config; 293 294 u8 config_set; ··· 1064 1063 return IRQ_HANDLED; 1065 1064 } 1066 1065 1066 + static int stm32_dma3_get_chan_sem(struct stm32_dma3_chan *chan) 1067 + { 1068 + struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); 1069 + u32 csemcr, ccid; 1070 + 1071 + csemcr = readl_relaxed(ddata->base + STM32_DMA3_CSEMCR(chan->id)); 1072 + /* Make an attempt to take the channel semaphore if not already taken */ 1073 + if (!(csemcr & CSEMCR_SEM_MUTEX)) { 1074 + writel_relaxed(CSEMCR_SEM_MUTEX, ddata->base + STM32_DMA3_CSEMCR(chan->id)); 1075 + csemcr = readl_relaxed(ddata->base + STM32_DMA3_CSEMCR(chan->id)); 1076 + } 1077 + 1078 + /* Check if channel is under CID1 control */ 1079 + ccid = FIELD_GET(CSEMCR_SEM_CCID, csemcr); 1080 + if (!(csemcr & CSEMCR_SEM_MUTEX) || ccid != CCIDCFGR_CID1) 1081 + goto bad_cid; 1082 + 1083 + chan->semaphore_taken = true; 1084 + dev_dbg(chan2dev(chan), "under CID1 control (semcr=0x%08x)\n", csemcr); 1085 + 1086 + return 0; 1087 + 1088 + bad_cid: 1089 + chan->semaphore_taken = false; 1090 + dev_err(chan2dev(chan), "not under CID1 control (in-use by CID%d)\n", ccid); 1091 + 1092 + return -EACCES; 1093 + } 1094 + 1095 + static void stm32_dma3_put_chan_sem(struct stm32_dma3_chan *chan) 1096 + { 1097 + struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); 1098 + 1099 + if (chan->semaphore_taken) { 1100 + writel_relaxed(0, ddata->base + STM32_DMA3_CSEMCR(chan->id)); 1101 + chan->semaphore_taken = false; 1102 + dev_dbg(chan2dev(chan), "no more under CID1 control\n"); 1103 + } 1104 + } 1105 + 1067 1106 static int stm32_dma3_alloc_chan_resources(struct dma_chan *c) 1068 1107 { 1069 1108 struct stm32_dma3_chan *chan = to_stm32_dma3_chan(c); 1070 1109 struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); 1071 - u32 id = chan->id, csemcr, ccid; 1072 1110 int ret; 1073 1111 1074 1112 ret = pm_runtime_resume_and_get(ddata->dma_dev.dev); ··· 1132 1092 1133 1093 /* Take the channel semaphore */ 1134 1094 if (chan->semaphore_mode) { 1135 - writel_relaxed(CSEMCR_SEM_MUTEX, ddata->base + STM32_DMA3_CSEMCR(id)); 1136 - csemcr = readl_relaxed(ddata->base + STM32_DMA3_CSEMCR(id)); 1137 - ccid = FIELD_GET(CSEMCR_SEM_CCID, csemcr); 1138 - /* Check that the channel is well taken */ 1139 - if (ccid != CCIDCFGR_CID1) { 1140 - dev_err(chan2dev(chan), "Not under CID1 control (in-use by CID%d)\n", ccid); 1141 - ret = -EPERM; 1095 + ret = stm32_dma3_get_chan_sem(chan); 1096 + if (ret) 1142 1097 goto err_pool_destroy; 1143 - } 1144 - dev_dbg(chan2dev(chan), "Under CID1 control (semcr=0x%08x)\n", csemcr); 1145 1098 } 1146 1099 1147 1100 return 0; ··· 1168 1135 1169 1136 /* Release the channel semaphore */ 1170 1137 if (chan->semaphore_mode) 1171 - writel_relaxed(0, ddata->base + STM32_DMA3_CSEMCR(chan->id)); 1138 + stm32_dma3_put_chan_sem(chan); 1172 1139 1173 1140 pm_runtime_put_sync(ddata->dma_dev.dev); 1174 1141