1afbdcc7cSSagar Dharia // SPDX-License-Identifier: GPL-2.0
2afbdcc7cSSagar Dharia /*
3afbdcc7cSSagar Dharia * Copyright (c) 2011-2017, The Linux Foundation
4afbdcc7cSSagar Dharia */
5afbdcc7cSSagar Dharia
6afbdcc7cSSagar Dharia #include <linux/slab.h>
74b14e62aSSagar Dharia #include <linux/pm_runtime.h>
8afbdcc7cSSagar Dharia #include "slimbus.h"
9afbdcc7cSSagar Dharia
10afbdcc7cSSagar Dharia /**
11afbdcc7cSSagar Dharia * slim_msg_response() - Deliver Message response received from a device to the
12afbdcc7cSSagar Dharia * framework.
13afbdcc7cSSagar Dharia *
14afbdcc7cSSagar Dharia * @ctrl: Controller handle
15afbdcc7cSSagar Dharia * @reply: Reply received from the device
16afbdcc7cSSagar Dharia * @len: Length of the reply
17afbdcc7cSSagar Dharia * @tid: Transaction ID received with which framework can associate reply.
18afbdcc7cSSagar Dharia *
19afbdcc7cSSagar Dharia * Called by controller to inform framework about the response received.
20afbdcc7cSSagar Dharia * This helps in making the API asynchronous, and controller-driver doesn't need
21afbdcc7cSSagar Dharia * to manage 1 more table other than the one managed by framework mapping TID
22afbdcc7cSSagar Dharia * with buffers
23afbdcc7cSSagar Dharia */
slim_msg_response(struct slim_controller * ctrl,u8 * reply,u8 tid,u8 len)24afbdcc7cSSagar Dharia void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
25afbdcc7cSSagar Dharia {
26afbdcc7cSSagar Dharia struct slim_msg_txn *txn;
27afbdcc7cSSagar Dharia struct slim_val_inf *msg;
28afbdcc7cSSagar Dharia unsigned long flags;
29afbdcc7cSSagar Dharia
30afbdcc7cSSagar Dharia spin_lock_irqsave(&ctrl->txn_lock, flags);
31afbdcc7cSSagar Dharia txn = idr_find(&ctrl->tid_idr, tid);
32afbdcc7cSSagar Dharia spin_unlock_irqrestore(&ctrl->txn_lock, flags);
33d3062a21SSrinivas Kandagatla
34d3062a21SSrinivas Kandagatla if (txn == NULL)
35afbdcc7cSSagar Dharia return;
36afbdcc7cSSagar Dharia
37afbdcc7cSSagar Dharia msg = txn->msg;
38afbdcc7cSSagar Dharia if (msg == NULL || msg->rbuf == NULL) {
39afbdcc7cSSagar Dharia dev_err(ctrl->dev, "Got response to invalid TID:%d, len:%d\n",
40afbdcc7cSSagar Dharia tid, len);
41afbdcc7cSSagar Dharia return;
42afbdcc7cSSagar Dharia }
43afbdcc7cSSagar Dharia
44d3062a21SSrinivas Kandagatla slim_free_txn_tid(ctrl, txn);
45afbdcc7cSSagar Dharia memcpy(msg->rbuf, reply, len);
46afbdcc7cSSagar Dharia if (txn->comp)
47afbdcc7cSSagar Dharia complete(txn->comp);
484b14e62aSSagar Dharia
494b14e62aSSagar Dharia /* Remove runtime-pm vote now that response was received for TID txn */
504b14e62aSSagar Dharia pm_runtime_mark_last_busy(ctrl->dev);
514b14e62aSSagar Dharia pm_runtime_put_autosuspend(ctrl->dev);
52afbdcc7cSSagar Dharia }
53afbdcc7cSSagar Dharia EXPORT_SYMBOL_GPL(slim_msg_response);
54afbdcc7cSSagar Dharia
55afbdcc7cSSagar Dharia /**
56d3062a21SSrinivas Kandagatla * slim_alloc_txn_tid() - Allocate a tid to txn
57d3062a21SSrinivas Kandagatla *
58d3062a21SSrinivas Kandagatla * @ctrl: Controller handle
59d3062a21SSrinivas Kandagatla * @txn: transaction to be allocated with tid.
60d3062a21SSrinivas Kandagatla *
61d3062a21SSrinivas Kandagatla * Return: zero on success with valid txn->tid and error code on failures.
62d3062a21SSrinivas Kandagatla */
slim_alloc_txn_tid(struct slim_controller * ctrl,struct slim_msg_txn * txn)63d3062a21SSrinivas Kandagatla int slim_alloc_txn_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn)
64d3062a21SSrinivas Kandagatla {
65d3062a21SSrinivas Kandagatla unsigned long flags;
66d3062a21SSrinivas Kandagatla int ret = 0;
67d3062a21SSrinivas Kandagatla
68d3062a21SSrinivas Kandagatla spin_lock_irqsave(&ctrl->txn_lock, flags);
699659281cSSrinivas Kandagatla ret = idr_alloc_cyclic(&ctrl->tid_idr, txn, 1,
70d3062a21SSrinivas Kandagatla SLIM_MAX_TIDS, GFP_ATOMIC);
71d3062a21SSrinivas Kandagatla if (ret < 0) {
72d3062a21SSrinivas Kandagatla spin_unlock_irqrestore(&ctrl->txn_lock, flags);
73d3062a21SSrinivas Kandagatla return ret;
74d3062a21SSrinivas Kandagatla }
75d3062a21SSrinivas Kandagatla txn->tid = ret;
76d3062a21SSrinivas Kandagatla spin_unlock_irqrestore(&ctrl->txn_lock, flags);
77d3062a21SSrinivas Kandagatla return 0;
78d3062a21SSrinivas Kandagatla }
79d3062a21SSrinivas Kandagatla EXPORT_SYMBOL_GPL(slim_alloc_txn_tid);
80d3062a21SSrinivas Kandagatla
81d3062a21SSrinivas Kandagatla /**
8289e1ec77SJulia Lawall * slim_free_txn_tid() - Free tid of txn
83d3062a21SSrinivas Kandagatla *
84d3062a21SSrinivas Kandagatla * @ctrl: Controller handle
85d3062a21SSrinivas Kandagatla * @txn: transaction whose tid should be freed
86d3062a21SSrinivas Kandagatla */
slim_free_txn_tid(struct slim_controller * ctrl,struct slim_msg_txn * txn)87d3062a21SSrinivas Kandagatla void slim_free_txn_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn)
88d3062a21SSrinivas Kandagatla {
89d3062a21SSrinivas Kandagatla unsigned long flags;
90d3062a21SSrinivas Kandagatla
91d3062a21SSrinivas Kandagatla spin_lock_irqsave(&ctrl->txn_lock, flags);
92d3062a21SSrinivas Kandagatla idr_remove(&ctrl->tid_idr, txn->tid);
93d3062a21SSrinivas Kandagatla spin_unlock_irqrestore(&ctrl->txn_lock, flags);
94d3062a21SSrinivas Kandagatla }
95d3062a21SSrinivas Kandagatla EXPORT_SYMBOL_GPL(slim_free_txn_tid);
96d3062a21SSrinivas Kandagatla
97d3062a21SSrinivas Kandagatla /**
98afbdcc7cSSagar Dharia * slim_do_transfer() - Process a SLIMbus-messaging transaction
99afbdcc7cSSagar Dharia *
100afbdcc7cSSagar Dharia * @ctrl: Controller handle
101afbdcc7cSSagar Dharia * @txn: Transaction to be sent over SLIMbus
102afbdcc7cSSagar Dharia *
103afbdcc7cSSagar Dharia * Called by controller to transmit messaging transactions not dealing with
10489e1ec77SJulia Lawall * Interface/Value elements. (e.g. transmitting a message to assign logical
105afbdcc7cSSagar Dharia * address to a slave device
106afbdcc7cSSagar Dharia *
107afbdcc7cSSagar Dharia * Return: -ETIMEDOUT: If transmission of this message timed out
108afbdcc7cSSagar Dharia * (e.g. due to bus lines not being clocked or driven by controller)
109afbdcc7cSSagar Dharia */
slim_do_transfer(struct slim_controller * ctrl,struct slim_msg_txn * txn)110afbdcc7cSSagar Dharia int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
111afbdcc7cSSagar Dharia {
112afbdcc7cSSagar Dharia DECLARE_COMPLETION_ONSTACK(done);
1134b14e62aSSagar Dharia bool need_tid = false, clk_pause_msg = false;
114d3062a21SSrinivas Kandagatla int ret, timeout;
115afbdcc7cSSagar Dharia
1164b14e62aSSagar Dharia /*
1174b14e62aSSagar Dharia * do not vote for runtime-PM if the transactions are part of clock
1184b14e62aSSagar Dharia * pause sequence
1194b14e62aSSagar Dharia */
1204b14e62aSSagar Dharia if (ctrl->sched.clk_state == SLIM_CLK_ENTERING_PAUSE &&
1214b14e62aSSagar Dharia (txn->mt == SLIM_MSG_MT_CORE &&
1224b14e62aSSagar Dharia txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
1234b14e62aSSagar Dharia txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
1244b14e62aSSagar Dharia clk_pause_msg = true;
1254b14e62aSSagar Dharia
1264b14e62aSSagar Dharia if (!clk_pause_msg) {
1274b14e62aSSagar Dharia ret = pm_runtime_get_sync(ctrl->dev);
1284b14e62aSSagar Dharia if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
1294b14e62aSSagar Dharia dev_err(ctrl->dev, "ctrl wrong state:%d, ret:%d\n",
1304b14e62aSSagar Dharia ctrl->sched.clk_state, ret);
1314b14e62aSSagar Dharia goto slim_xfer_err;
1324b14e62aSSagar Dharia }
1334b14e62aSSagar Dharia }
134a263c1ffSSrinivas Kandagatla /* Initialize tid to invalid value */
135a263c1ffSSrinivas Kandagatla txn->tid = 0;
136afbdcc7cSSagar Dharia need_tid = slim_tid_txn(txn->mt, txn->mc);
137afbdcc7cSSagar Dharia
138afbdcc7cSSagar Dharia if (need_tid) {
139d3062a21SSrinivas Kandagatla ret = slim_alloc_txn_tid(ctrl, txn);
140d3062a21SSrinivas Kandagatla if (ret)
141d3062a21SSrinivas Kandagatla return ret;
142afbdcc7cSSagar Dharia
143afbdcc7cSSagar Dharia if (!txn->msg->comp)
144afbdcc7cSSagar Dharia txn->comp = &done;
145afbdcc7cSSagar Dharia else
146afbdcc7cSSagar Dharia txn->comp = txn->comp;
147afbdcc7cSSagar Dharia }
148afbdcc7cSSagar Dharia
149afbdcc7cSSagar Dharia ret = ctrl->xfer_msg(ctrl, txn);
150*faac8e89SVisweswara Tanuku if (ret == -ETIMEDOUT) {
151*faac8e89SVisweswara Tanuku slim_free_txn_tid(ctrl, txn);
152*faac8e89SVisweswara Tanuku } else if (!ret && need_tid && !txn->msg->comp) {
153afbdcc7cSSagar Dharia unsigned long ms = txn->rl + HZ;
154afbdcc7cSSagar Dharia
155afbdcc7cSSagar Dharia timeout = wait_for_completion_timeout(txn->comp,
156afbdcc7cSSagar Dharia msecs_to_jiffies(ms));
157afbdcc7cSSagar Dharia if (!timeout) {
158afbdcc7cSSagar Dharia ret = -ETIMEDOUT;
159d3062a21SSrinivas Kandagatla slim_free_txn_tid(ctrl, txn);
160afbdcc7cSSagar Dharia }
161afbdcc7cSSagar Dharia }
162afbdcc7cSSagar Dharia
163afbdcc7cSSagar Dharia if (ret)
164afbdcc7cSSagar Dharia dev_err(ctrl->dev, "Tx:MT:0x%x, MC:0x%x, LA:0x%x failed:%d\n",
165afbdcc7cSSagar Dharia txn->mt, txn->mc, txn->la, ret);
166afbdcc7cSSagar Dharia
1674b14e62aSSagar Dharia slim_xfer_err:
168a263c1ffSSrinivas Kandagatla if (!clk_pause_msg && (txn->tid == 0 || ret == -ETIMEDOUT)) {
1694b14e62aSSagar Dharia /*
1704b14e62aSSagar Dharia * remove runtime-pm vote if this was TX only, or
1714b14e62aSSagar Dharia * if there was error during this transaction
1724b14e62aSSagar Dharia */
1734b14e62aSSagar Dharia pm_runtime_mark_last_busy(ctrl->dev);
174057ba872SSrinivas Kandagatla pm_runtime_put_autosuspend(ctrl->dev);
1754b14e62aSSagar Dharia }
176afbdcc7cSSagar Dharia return ret;
177afbdcc7cSSagar Dharia }
178afbdcc7cSSagar Dharia EXPORT_SYMBOL_GPL(slim_do_transfer);
179afbdcc7cSSagar Dharia
slim_val_inf_sanity(struct slim_controller * ctrl,struct slim_val_inf * msg,u8 mc)180afbdcc7cSSagar Dharia static int slim_val_inf_sanity(struct slim_controller *ctrl,
181afbdcc7cSSagar Dharia struct slim_val_inf *msg, u8 mc)
182afbdcc7cSSagar Dharia {
183afbdcc7cSSagar Dharia if (!msg || msg->num_bytes > 16 ||
184afbdcc7cSSagar Dharia (msg->start_offset + msg->num_bytes) > 0xC00)
185afbdcc7cSSagar Dharia goto reterr;
186afbdcc7cSSagar Dharia switch (mc) {
187afbdcc7cSSagar Dharia case SLIM_MSG_MC_REQUEST_VALUE:
188afbdcc7cSSagar Dharia case SLIM_MSG_MC_REQUEST_INFORMATION:
189afbdcc7cSSagar Dharia if (msg->rbuf != NULL)
190afbdcc7cSSagar Dharia return 0;
191afbdcc7cSSagar Dharia break;
192afbdcc7cSSagar Dharia
193afbdcc7cSSagar Dharia case SLIM_MSG_MC_CHANGE_VALUE:
194afbdcc7cSSagar Dharia case SLIM_MSG_MC_CLEAR_INFORMATION:
195afbdcc7cSSagar Dharia if (msg->wbuf != NULL)
196afbdcc7cSSagar Dharia return 0;
197afbdcc7cSSagar Dharia break;
198afbdcc7cSSagar Dharia
199afbdcc7cSSagar Dharia case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
200afbdcc7cSSagar Dharia case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
201afbdcc7cSSagar Dharia if (msg->rbuf != NULL && msg->wbuf != NULL)
202afbdcc7cSSagar Dharia return 0;
203afbdcc7cSSagar Dharia break;
204afbdcc7cSSagar Dharia }
205afbdcc7cSSagar Dharia reterr:
2067dde60c0SColin Ian King if (msg)
207afbdcc7cSSagar Dharia dev_err(ctrl->dev, "Sanity check failed:msg:offset:0x%x, mc:%d\n",
208afbdcc7cSSagar Dharia msg->start_offset, mc);
209afbdcc7cSSagar Dharia return -EINVAL;
210afbdcc7cSSagar Dharia }
211afbdcc7cSSagar Dharia
slim_slicesize(int code)212afbdcc7cSSagar Dharia static u16 slim_slicesize(int code)
213afbdcc7cSSagar Dharia {
214afbdcc7cSSagar Dharia static const u8 sizetocode[16] = {
215afbdcc7cSSagar Dharia 0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7
216afbdcc7cSSagar Dharia };
217afbdcc7cSSagar Dharia
218e33bbe69SGeert Uytterhoeven code = clamp(code, 1, (int)ARRAY_SIZE(sizetocode));
219afbdcc7cSSagar Dharia
220afbdcc7cSSagar Dharia return sizetocode[code - 1];
221afbdcc7cSSagar Dharia }
222afbdcc7cSSagar Dharia
223afbdcc7cSSagar Dharia /**
224afbdcc7cSSagar Dharia * slim_xfer_msg() - Transfer a value info message on slim device
225afbdcc7cSSagar Dharia *
226afbdcc7cSSagar Dharia * @sbdev: slim device to which this msg has to be transfered
227afbdcc7cSSagar Dharia * @msg: value info message pointer
228afbdcc7cSSagar Dharia * @mc: message code of the message
229afbdcc7cSSagar Dharia *
230afbdcc7cSSagar Dharia * Called by drivers which want to transfer a vlaue or info elements.
231afbdcc7cSSagar Dharia *
232afbdcc7cSSagar Dharia * Return: -ETIMEDOUT: If transmission of this message timed out
233afbdcc7cSSagar Dharia */
slim_xfer_msg(struct slim_device * sbdev,struct slim_val_inf * msg,u8 mc)234afbdcc7cSSagar Dharia int slim_xfer_msg(struct slim_device *sbdev, struct slim_val_inf *msg,
235afbdcc7cSSagar Dharia u8 mc)
236afbdcc7cSSagar Dharia {
237afbdcc7cSSagar Dharia DEFINE_SLIM_LDEST_TXN(txn_stack, mc, 6, sbdev->laddr, msg);
238afbdcc7cSSagar Dharia struct slim_msg_txn *txn = &txn_stack;
239afbdcc7cSSagar Dharia struct slim_controller *ctrl = sbdev->ctrl;
240afbdcc7cSSagar Dharia int ret;
241afbdcc7cSSagar Dharia u16 sl;
242afbdcc7cSSagar Dharia
243afbdcc7cSSagar Dharia if (!ctrl)
244afbdcc7cSSagar Dharia return -EINVAL;
245afbdcc7cSSagar Dharia
246afbdcc7cSSagar Dharia ret = slim_val_inf_sanity(ctrl, msg, mc);
247afbdcc7cSSagar Dharia if (ret)
248afbdcc7cSSagar Dharia return ret;
249afbdcc7cSSagar Dharia
250afbdcc7cSSagar Dharia sl = slim_slicesize(msg->num_bytes);
251afbdcc7cSSagar Dharia
252afbdcc7cSSagar Dharia dev_dbg(ctrl->dev, "SB xfer msg:os:%x, len:%d, MC:%x, sl:%x\n",
253afbdcc7cSSagar Dharia msg->start_offset, msg->num_bytes, mc, sl);
254afbdcc7cSSagar Dharia
255afbdcc7cSSagar Dharia txn->ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4));
256afbdcc7cSSagar Dharia
257afbdcc7cSSagar Dharia switch (mc) {
258afbdcc7cSSagar Dharia case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
259afbdcc7cSSagar Dharia case SLIM_MSG_MC_CHANGE_VALUE:
260afbdcc7cSSagar Dharia case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
261afbdcc7cSSagar Dharia case SLIM_MSG_MC_CLEAR_INFORMATION:
262afbdcc7cSSagar Dharia txn->rl += msg->num_bytes;
26350df9842SGustavo A. R. Silva break;
264afbdcc7cSSagar Dharia default:
265afbdcc7cSSagar Dharia break;
266afbdcc7cSSagar Dharia }
267afbdcc7cSSagar Dharia
268afbdcc7cSSagar Dharia if (slim_tid_txn(txn->mt, txn->mc))
269afbdcc7cSSagar Dharia txn->rl++;
270afbdcc7cSSagar Dharia
271afbdcc7cSSagar Dharia return slim_do_transfer(ctrl, txn);
272afbdcc7cSSagar Dharia }
273afbdcc7cSSagar Dharia EXPORT_SYMBOL_GPL(slim_xfer_msg);
274afbdcc7cSSagar Dharia
slim_fill_msg(struct slim_val_inf * msg,u32 addr,size_t count,u8 * rbuf,u8 * wbuf)275afbdcc7cSSagar Dharia static void slim_fill_msg(struct slim_val_inf *msg, u32 addr,
276afbdcc7cSSagar Dharia size_t count, u8 *rbuf, u8 *wbuf)
277afbdcc7cSSagar Dharia {
278afbdcc7cSSagar Dharia msg->start_offset = addr;
279afbdcc7cSSagar Dharia msg->num_bytes = count;
280afbdcc7cSSagar Dharia msg->rbuf = rbuf;
281afbdcc7cSSagar Dharia msg->wbuf = wbuf;
282ffa2d921SSrinivas Kandagatla msg->comp = NULL;
283afbdcc7cSSagar Dharia }
284afbdcc7cSSagar Dharia
285afbdcc7cSSagar Dharia /**
286afbdcc7cSSagar Dharia * slim_read() - Read SLIMbus value element
287afbdcc7cSSagar Dharia *
288afbdcc7cSSagar Dharia * @sdev: client handle.
289afbdcc7cSSagar Dharia * @addr: address of value element to read.
290afbdcc7cSSagar Dharia * @count: number of bytes to read. Maximum bytes allowed are 16.
291afbdcc7cSSagar Dharia * @val: will return what the value element value was
292afbdcc7cSSagar Dharia *
293afbdcc7cSSagar Dharia * Return: -EINVAL for Invalid parameters, -ETIMEDOUT If transmission of
294afbdcc7cSSagar Dharia * this message timed out (e.g. due to bus lines not being clocked
295afbdcc7cSSagar Dharia * or driven by controller)
296afbdcc7cSSagar Dharia */
slim_read(struct slim_device * sdev,u32 addr,size_t count,u8 * val)297afbdcc7cSSagar Dharia int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
298afbdcc7cSSagar Dharia {
299afbdcc7cSSagar Dharia struct slim_val_inf msg;
300afbdcc7cSSagar Dharia
301afbdcc7cSSagar Dharia slim_fill_msg(&msg, addr, count, val, NULL);
302afbdcc7cSSagar Dharia
303afbdcc7cSSagar Dharia return slim_xfer_msg(sdev, &msg, SLIM_MSG_MC_REQUEST_VALUE);
304afbdcc7cSSagar Dharia }
305afbdcc7cSSagar Dharia EXPORT_SYMBOL_GPL(slim_read);
306afbdcc7cSSagar Dharia
307afbdcc7cSSagar Dharia /**
308afbdcc7cSSagar Dharia * slim_readb() - Read byte from SLIMbus value element
309afbdcc7cSSagar Dharia *
310afbdcc7cSSagar Dharia * @sdev: client handle.
311afbdcc7cSSagar Dharia * @addr: address in the value element to read.
312afbdcc7cSSagar Dharia *
313afbdcc7cSSagar Dharia * Return: byte value of value element.
314afbdcc7cSSagar Dharia */
slim_readb(struct slim_device * sdev,u32 addr)315afbdcc7cSSagar Dharia int slim_readb(struct slim_device *sdev, u32 addr)
316afbdcc7cSSagar Dharia {
317afbdcc7cSSagar Dharia int ret;
318afbdcc7cSSagar Dharia u8 buf;
319afbdcc7cSSagar Dharia
320afbdcc7cSSagar Dharia ret = slim_read(sdev, addr, 1, &buf);
321afbdcc7cSSagar Dharia if (ret < 0)
322afbdcc7cSSagar Dharia return ret;
323afbdcc7cSSagar Dharia else
324afbdcc7cSSagar Dharia return buf;
325afbdcc7cSSagar Dharia }
326afbdcc7cSSagar Dharia EXPORT_SYMBOL_GPL(slim_readb);
327afbdcc7cSSagar Dharia
328afbdcc7cSSagar Dharia /**
329afbdcc7cSSagar Dharia * slim_write() - Write SLIMbus value element
330afbdcc7cSSagar Dharia *
331afbdcc7cSSagar Dharia * @sdev: client handle.
332afbdcc7cSSagar Dharia * @addr: address in the value element to write.
333afbdcc7cSSagar Dharia * @count: number of bytes to write. Maximum bytes allowed are 16.
334afbdcc7cSSagar Dharia * @val: value to write to value element
335afbdcc7cSSagar Dharia *
336afbdcc7cSSagar Dharia * Return: -EINVAL for Invalid parameters, -ETIMEDOUT If transmission of
337afbdcc7cSSagar Dharia * this message timed out (e.g. due to bus lines not being clocked
338afbdcc7cSSagar Dharia * or driven by controller)
339afbdcc7cSSagar Dharia */
slim_write(struct slim_device * sdev,u32 addr,size_t count,u8 * val)340afbdcc7cSSagar Dharia int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
341afbdcc7cSSagar Dharia {
342afbdcc7cSSagar Dharia struct slim_val_inf msg;
343afbdcc7cSSagar Dharia
3448134d271SSrinivas Kandagatla slim_fill_msg(&msg, addr, count, NULL, val);
345afbdcc7cSSagar Dharia
346afbdcc7cSSagar Dharia return slim_xfer_msg(sdev, &msg, SLIM_MSG_MC_CHANGE_VALUE);
347afbdcc7cSSagar Dharia }
348afbdcc7cSSagar Dharia EXPORT_SYMBOL_GPL(slim_write);
349afbdcc7cSSagar Dharia
350afbdcc7cSSagar Dharia /**
351afbdcc7cSSagar Dharia * slim_writeb() - Write byte to SLIMbus value element
352afbdcc7cSSagar Dharia *
353afbdcc7cSSagar Dharia * @sdev: client handle.
354afbdcc7cSSagar Dharia * @addr: address of value element to write.
355afbdcc7cSSagar Dharia * @value: value to write to value element
356afbdcc7cSSagar Dharia *
357afbdcc7cSSagar Dharia * Return: -EINVAL for Invalid parameters, -ETIMEDOUT If transmission of
358afbdcc7cSSagar Dharia * this message timed out (e.g. due to bus lines not being clocked
359afbdcc7cSSagar Dharia * or driven by controller)
360afbdcc7cSSagar Dharia *
361afbdcc7cSSagar Dharia */
slim_writeb(struct slim_device * sdev,u32 addr,u8 value)362afbdcc7cSSagar Dharia int slim_writeb(struct slim_device *sdev, u32 addr, u8 value)
363afbdcc7cSSagar Dharia {
364afbdcc7cSSagar Dharia return slim_write(sdev, addr, 1, &value);
365afbdcc7cSSagar Dharia }
366afbdcc7cSSagar Dharia EXPORT_SYMBOL_GPL(slim_writeb);
367