tree:
https://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
serdev-ngsm-pending-v5.7
head: 4eda51fea6be98ca5a4023a988b102bf3629b295
commit: ae348e86a0abccb615c8875a95d63f10268f1c4f [20/29] gnss: motmdm: Add support for
Motorola Mapphone MDM6600 modem
config: riscv-allyesconfig (attached as .config)
compiler: riscv64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O
~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout ae348e86a0abccb615c8875a95d63f10268f1c4f
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=riscv
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp(a)intel.com>
All warnings (new ones prefixed by >>, old ones prefixed by <<):
> drivers/gnss/motmdm.c:71:5: warning: no previous prototype for
'motmdm_gnss_send_command' [-Wmissing-prototypes]
71 | int
motmdm_gnss_send_command(struct motmdm_gnss_data *ddata,
| ^~~~~~~~~~~~~~~~~~~~~~~~
drivers/gnss/motmdm.c: In function 'motmdm_gnss_receive_data':
> drivers/gnss/motmdm.c:209:6: warning: variable 'error'
set but not used [-Wunused-but-set-variable]
209 | int error = 0;
| ^~~~~
vim +/motmdm_gnss_send_command +71 drivers/gnss/motmdm.c
62
63 /*
64 * Note that multiple commands can be sent in series with responses coming
65 * out-of-order. For GNSS, we don't need to care about the out-of-order
66 * responses, and can assume we have at most one command active at a time.
67 * For the commands, can use just a jiffies base packet ID and let the modem
68 * sort out the ID conflicts with the modem's unsolicited message ID
69 * numbering.
70 */
71 int motmdm_gnss_send_command(struct motmdm_gnss_data *ddata,
72 const u8 *buf, int len)
73 {
74 struct gnss_device *gdev = ddata->gdev;
75 const int timeout_ms = 1000;
76 unsigned char cmd[128];
77 int ret, cmdlen;
78
79 cmdlen = len + 5 + 1;
80 if (cmdlen > 128)
81 return -EINVAL;
82
83 mutex_lock(&ddata->mutex);
84 memset(ddata->buf, 0, ddata->len);
85 ddata->parsed = false;
86 snprintf(cmd, cmdlen, "U%04li%s", jiffies % 10000, buf);
87 ret = serdev_ngsm_write(ddata->modem, &ddata->dlci, cmd, cmdlen);
88 if (ret < 0)
89 goto out_unlock;
90
91 ret = wait_event_timeout(ddata->read_queue, ddata->parsed,
92 msecs_to_jiffies(timeout_ms));
93 if (ret == 0) {
94 ret = -ETIMEDOUT;
95 goto out_unlock;
96 } else if (ret < 0) {
97 goto out_unlock;
98 }
99
100 if (!strstr(ddata->buf, ":OK")) {
101 dev_err(&gdev->dev, "command %s error %s\n",
102 cmd, ddata->buf);
103 ret = -EPIPE;
104 }
105
106 ret = len;
107
108 out_unlock:
109 mutex_unlock(&ddata->mutex);
110
111 return ret;
112 }
113
114 /*
115 * Android uses AT+MPDSTART=0,1,100,0 which starts GNSS for a while,
116 * and then GNSS needs to be kicked with an AT command based on a
117 * status message.
118 */
119 static void motmdm_gnss_restart(struct work_struct *work)
120 {
121 struct motmdm_gnss_data *ddata =
122 container_of(work, struct motmdm_gnss_data,
123 restart_work.work);
124 struct gnss_device *gdev = ddata->gdev;
125 const unsigned char *cmd = "AT+MPDSTART=0,1,100,0";
126 int error;
127
128 ddata->last_update = ktime_get();
129
130 error = motmdm_gnss_send_command(ddata, cmd, strlen(cmd));
131 if (error < 0) {
132 /* Timeouts can happen, don't warn and try again */
133 if (error != -ETIMEDOUT)
134 dev_warn(&gdev->dev, "%s: could not start: %i\n",
135 __func__, error);
136
137 schedule_delayed_work(&ddata->restart_work,
138 msecs_to_jiffies(MOTMDM_GNSS_RATE));
139
140 return;
141 }
142 }
143
144 static void motmdm_gnss_start(struct gnss_device *gdev, int delay_ms)
145 {
146 struct motmdm_gnss_data *ddata = gnss_get_drvdata(gdev);
147 ktime_t now, next, delta;
148 int next_ms;
149
150 now = ktime_get();
151 next = ktime_add_ms(ddata->last_update, delay_ms);
152 delta = ktime_sub(next, now);
153 next_ms = ktime_to_ms(delta);
154
155 if (next_ms < 0)
156 next_ms = 0;
157 if (next_ms > delay_ms)
158 next_ms = delay_ms;
159
160 schedule_delayed_work(&ddata->restart_work, msecs_to_jiffies(next_ms));
161 }
162
163 static int motmdm_gnss_stop(struct gnss_device *gdev)
164 {
165 struct motmdm_gnss_data *ddata = gnss_get_drvdata(gdev);
166 const unsigned char *cmd = "AT+MPDSTOP";
167
168 cancel_delayed_work_sync(&ddata->restart_work);
169
170 return motmdm_gnss_send_command(ddata, cmd, strlen(cmd));
171 }
172
173 static int motmdm_gnss_init(struct gnss_device *gdev)
174 {
175 struct motmdm_gnss_data *ddata = gnss_get_drvdata(gdev);
176 const unsigned char *cmd = "AT+MPDINIT=1";
177 int error;
178
179 error = motmdm_gnss_send_command(ddata, cmd, strlen(cmd));
180 if (error < 0)
181 return error;
182
183 motmdm_gnss_start(gdev, 0);
184
185 return 0;
186 }
187
188 static int motmdm_gnss_finish(struct gnss_device *gdev)
189 {
190 struct motmdm_gnss_data *ddata = gnss_get_drvdata(gdev);
191 const unsigned char *cmd = "AT+MPDINIT=0";
192 int error;
193
194 error = motmdm_gnss_stop(gdev);
195 if (error < 0)
196 return error;
197
198 return motmdm_gnss_send_command(ddata, cmd, strlen(cmd));
199 }
200
201 static int motmdm_gnss_receive_data(struct gsm_serdev_dlci *dlci,
202 const unsigned char *buf,
203 size_t len)
204 {
205 struct gnss_device *gdev = dlci->drvdata;
206 struct motmdm_gnss_data *ddata = gnss_get_drvdata(gdev);
207 const unsigned char *msg;
208 size_t msglen;
209 int error = 0;
210
211 if (len <= MOTMDM_GNSS_RESP_LEN)
212 return 0;
213
214 /* Handle U1234+MPD style command response */
215 if (buf[MOTMDM_GNSS_HEADER_LEN] != '~') {
216 msg = buf + MOTMDM_GNSS_RESP_LEN;
217 strncpy(ddata->buf, msg, len - MOTMDM_GNSS_RESP_LEN);
218 ddata->parsed = true;
219 wake_up(&ddata->read_queue);
220
221 return len;
222 }
223
224 if (len <= MOTMDM_GNSS_DATA_LEN)
225 return 0;
226
227 /* Handle U1234~+MPD style unsolicted message */
228 switch (buf[MOTMDM_GNSS_DATA_LEN]) {
229 case 'N': /* UNNNN~+MPDNMEA=NN, */
230 msg = buf + MOTMDM_GNSS_NMEA_LEN;
231 msglen = len - MOTMDM_GNSS_NMEA_LEN;
232
233 /*
234 * Firmware bug: Strip out extra duplicate line break always
235 * in the data
236 */
237 msglen--;
238
239 /*
240 * Firmware bug: Strip out extra data based on an
241 * earlier line break in the data
242 */
243 if (msg[msglen - 5 - 1] == 0x0a)
244 msglen -= 5;
245
246 error = gnss_insert_raw(gdev, msg, msglen);
247 break;
248 case 'S': /* UNNNN~+MPDSTATUS=N,NN */
249 msg = buf + MOTMDM_GNSS_STATUS_LEN;
250 msglen = len - MOTMDM_GNSS_STATUS_LEN;
251
252 switch (msg[0]) {
253 case '1':
254 ddata->status = MOTMDM_GNSS_INITIALIZED;
255 break;
256 case '2':
257 ddata->status = MOTMDM_GNSS_DATA_OR_TIMEOUT;
258 if (rate_ms < MOTMDM_GNSS_RATE)
259 rate_ms = MOTMDM_GNSS_RATE;
260 if (rate_ms > 16 * MOTMDM_GNSS_RATE)
261 rate_ms = 16 * MOTMDM_GNSS_RATE;
262 motmdm_gnss_start(gdev, rate_ms);
263 break;
264 case '3':
265 ddata->status = MOTMDM_GNSS_STARTED;
266 break;
267 case '4':
268 ddata->status = MOTMDM_GNSS_STOPPED;
269 break;
270 default:
271 ddata->status = MOTMDM_GNSS_UNKNOWN;
272 break;
273 }
274 break;
275 case 'X': /* UNNNN~+MPDXREQ=N for updated xtra2.bin needed */
276 default:
277 break;
278 }
279
280 return len;
281 }
282
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org