summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkhilesh Reddy Khumbum <akhumbum@nvidia.com>2016-05-02 13:15:30 -0400
committerLaxman Dewangan <ldewangan@nvidia.com>2016-05-11 12:10:44 -0400
commit292a80589a2377f1f8d41968e1b472ed929c11cf (patch)
treee2973baebcf38b94f6e05eb1ddd2b979df4bdd5d
parentefb3dc52908669c654cc64afef823be72867444b (diff)
spi: tegra: Add SPI proxy driver for AON SPI
SPI2 is accessible by both AON/SPE and CCPLEX. If both CPU's access the SPI bus at the same time, there will be a conflict. In order to ensure there are no conflicts, we select SPE as the owner of the SPI2 controller and all the other CPU's that need to touch the SPI2 controller will send an IPC message to the SPE and SPE will perform the SPI transaction on the requesting CPU's behalf. This driver registers as the standard kernel SPI controller driver for AON SPI controller i.e. SPI2. This driver sends the IPC messages comprising of the SPI transfers to SPE instead of directly programming the SPI registers. Bug 1701661 Change-Id: I149d2bdd938c3f3aa03a754c2cc0678758fbba9e Signed-off-by: Akhilesh Reddy Khumbum <akhumbum@nvidia.com> Reviewed-on: http://git-master/r/1117289 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Krishna Yarlagadda <kyarlagadda@nvidia.com> Tested-by: Krishna Yarlagadda <kyarlagadda@nvidia.com> Reviewed-by: Mustafa Bilgen <mbilgen@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
-rw-r--r--drivers/spi/Kconfig6
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/aon-spi-messages.h175
-rw-r--r--drivers/spi/spi-tegra-aon.c490
4 files changed, 672 insertions, 0 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index e967f041c..5dc8ca807 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -6,3 +6,9 @@ config QSPI_TEGRA186
6 QSPI driver for Nvidia Tegra210 QSPI Controller interface. This controller 6 QSPI driver for Nvidia Tegra210 QSPI Controller interface. This controller
7 is different from the spi controller and first time introduces on Tegra210 soc. 7 is different from the spi controller and first time introduces on Tegra210 soc.
8 8
9config SPI_TEGRA186_AON
10 bool "Tegra18x AON SPI proxy driver"
11 depends on ARCH_TEGRA_18x_SOC
12 default y
13 select TEGRA_IVC
14 select TEGRA_HSP
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 99aa54025..35efac7f4 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -4,4 +4,5 @@ ccflags-y += -Werror
4ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG 4ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG
5 5
6obj-$(CONFIG_QSPI_TEGRA186) += spi-tegra186-qspi.o 6obj-$(CONFIG_QSPI_TEGRA186) += spi-tegra186-qspi.o
7obj-$(CONFIG_SPI_TEGRA186_AON) += spi-tegra-aon.o
7 8
diff --git a/drivers/spi/aon-spi-messages.h b/drivers/spi/aon-spi-messages.h
new file mode 100644
index 000000000..c7e77db7d
--- /dev/null
+++ b/drivers/spi/aon-spi-messages.h
@@ -0,0 +1,175 @@
1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10
11#ifndef _AON_SPI_MESSAGES_H_
12#define _AON_SPI_MESSAGES_H_
13
14#include <linux/types.h>
15#define TEGRA_IVC_ALIGN 64
16/* 24640 is emperically derived by observing the max len transactions
17 * touch.
18 */
19#define AON_SPI_MAX_DATA_SIZE 24640
20
21/* All the enums and the fields inside the structs described in this header
22 * file supports only uX type, where X can be 8,16,32. For inter CPU commun-
23 * ication, it is more stable to use this type.
24 */
25
26/* This enum represents the types of spi requests assocaited
27 * with AON.
28 */
29enum aon_spi_request_type {
30 AON_SPI_REQUEST_TYPE_INIT = 1,
31 AON_SPI_REQUEST_TYPE_SETUP = 2,
32 AON_SPI_REQUEST_TYPE_XFER = 3,
33 AON_SPI_REQUEST_TYPE_SUSPEND = 4,
34 AON_SPI_REQUEST_TYPE_RESUME = 5,
35};
36
37/*
38 * This enum indicates the status of the request from CCPLEX.
39 */
40enum aon_spi_status {
41 AON_SPI_STATUS_OK = 0,
42 AON_SPI_STATUS_ERROR = 1,
43};
44
45/* This enum represents whether the current SPI transaction
46 * is a read or write. Also indicates whether the current
47 * message is the first or last in the context of a big xfer
48 * split into multiple xfers.
49 */
50enum aon_spi_xfer_flag {
51 AON_SPI_XFER_FLAG_WRITE = BIT(1),
52 AON_SPI_XFER_FLAG_READ = BIT(2),
53 AON_SPI_XFER_FIRST_MSG = BIT(3),
54 AON_SPI_XFER_LAST_MSG = BIT(4),
55 AON_SPI_XFER_HANDLE_CACHE = BIT(5),
56};
57
58/* This struct is used to setup the SPI client setup for AON
59 * SPI controller.
60 * Fields:
61 * cs_setup_clk_count: CS pin setup clock count
62 * cs_hold_clk_count: CS pin hold clock count
63 * cs_inactive_cycles: CS pin inactive clock count
64 * set_rx_tap_delay: Specify if the SPI device need to set
65 RX tap delay
66 * spi_max_clk_rate: Specify the default clock rate of SPI client
67 * spi_no_dma: Flag to indicate pio or dma mode
68 */
69struct aon_spi_setup_request {
70 u32 cs_setup_clk_count;
71 u32 cs_hold_clk_count;
72 u32 cs_inactive_cycles;
73 u32 spi_max_clk_rate;
74 u8 chip_select;
75 u8 set_rx_tap_delay;
76 bool spi_no_dma;
77};
78
79/* This struct indicates the parameters for SPI xfer from CCPLEX to SPE.
80 * Fields:
81 * spi_clk_rate: Specify clock rate for current transfer
82 * flags: Indicate first/last message
83 * length: Current transfer length
84 * tx_buf_offset: Offset in the data field of the aon_spi_xfer_request
85 * struct for tx_buf contents. The buffer memory need to
86 * be aligned for DMA transfer
87 * rx_buf_offset: Offset in the data field of the aon_spi_xfer_request
88 * struct for rx_buf. The buffer memory need to be
89 * aligned for DMA transfer
90 * chip_select: Chip select of the slave device
91 * bits_per_word: Select bits_per_word
92 * tx_nbits: Number of bits used for writing
93 * rx_nbits: Number of bits used for reading
94 *
95 * When SPI can transfer in 1x,2x or 4x. It can get this tranfer information
96 * from device through tx_nbits and rx_nbits. In Bi-direction, these
97 * two should both be set. User can set transfer mode with SPI_NBITS_SINGLE(1x)
98 * SPI_NBITS_DUAL(2x) and SPI_NBITS_QUAD(4x) to support these three transfer.
99 */
100struct aon_spi_xfer_params {
101 u32 spi_clk_rate;
102 /* enum aon_spi_xfer_flag */
103 u16 flags;
104 u16 length;
105 u16 tx_buf_offset;
106 u16 rx_buf_offset;
107 u16 mode;
108 u8 chip_select;
109 u8 bits_per_word;
110 u8 tx_nbits;
111 u8 rx_nbits;
112};
113
114/* This struct indicates the contents of the xfer request from CCPLEX to SPE
115 * for the AON SPI controller.
116 *
117 * Fields:
118 * xfers; Paramters for the current transfers.
119 * data: Buffer that holds the data for the current SPI ransaction.
120 * The size is aligned to the size of the cache line.
121 */
122struct aon_spi_xfer_request {
123 union {
124 struct aon_spi_xfer_params xfers;
125 u8 align_t[TEGRA_IVC_ALIGN - sizeof(u32)];
126 };
127 u8 data[AON_SPI_MAX_DATA_SIZE];
128};
129
130/* This structure indicates the contents of the response from the remote CPU
131 * i.e SPE for the previously requested transaction via CCPLEX proxy driver.
132 *
133 * Fields:
134 * data: This just matches the data field in the xfer request struct.
135 * All the response is stored in this buf and can be accessed by
136 * the offset fields known in the xfer params.
137 */
138struct aon_spi_xfer_response {
139 union {
140 u8 align_t[TEGRA_IVC_ALIGN - sizeof(u32)];
141 };
142 u8 data[AON_SPI_MAX_DATA_SIZE];
143};
144
145/* This structure indicates the current SPI request from CCPLEX to SPE for the
146 * AON SPI controller.
147 *
148 * Fields:
149 * req_type: Indicates the type of request. Supports init, setup and xfer.
150 * data: Union of structs of all the request types.
151 */
152struct aon_spi_request {
153 /* enum aon_spi_request_type */
154 u32 req_type;
155 union {
156 struct aon_spi_setup_request setup;
157 struct aon_spi_xfer_request xfer;
158 } data;
159};
160
161/* This structure indicates the response for the SPI request from SPE to CCPLEX
162 * for the AON SPI controller.
163 *
164 * Fields:
165 * status: Response in regard to the request i.e success/failure.
166 * data: Union of structs of all the response types.
167 */
168struct aon_spi_response {
169 u32 status;
170 union {
171 struct aon_spi_xfer_response xfer;
172 } data;
173};
174
175#endif
diff --git a/drivers/spi/spi-tegra-aon.c b/drivers/spi/spi-tegra-aon.c
new file mode 100644
index 000000000..5a7c253df
--- /dev/null
+++ b/drivers/spi/spi-tegra-aon.c
@@ -0,0 +1,490 @@
1/*
2 * SPI proxy driver for NVIDIA's Tegra186 AON SPI Controller.
3 *
4 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/of_device.h>
22#include <linux/spi/spi.h>
23#include <linux/spi/spi-tegra.h>
24#include <linux/tegra-aon.h>
25#include <linux/mailbox_client.h>
26
27#include "aon-spi-messages.h"
28
29#define SPI_DMA_TIMEOUT (msecs_to_jiffies(5000))
30#define MAX_HOLD_CYCLES 16
31#define SPI_DEFAULT_SPEED 25000000
32
33#define MAX_CHIP_SELECT 4
34#define SPI_DEF_CHIPSELECT 0
35
36#define SPI_DEFAULT_RX_TAP_DELAY 10
37
38/* block period in ms */
39#define TX_BLOCK_PERIOD 200
40
41struct tegra_aon_spi_chipdata {
42 bool set_rx_tap_delay;
43};
44
45struct tegra_spi_data {
46 struct device *dev;
47 struct spi_master *master;
48 u32 spi_max_frequency;
49 u8 def_chip_select;
50 const struct tegra_aon_spi_chipdata *chip_data;
51 struct completion *xfer_completion;
52 struct mbox_client cl;
53 struct mbox_chan *mbox;
54 struct tegra_spi_device_controller_data cdata[MAX_CHIP_SELECT];
55 struct aon_spi_response *spi_resp;
56 struct aon_spi_request *spi_req;
57};
58
59
60static struct tegra_spi_device_controller_data
61 *tegra_spi_get_cdata_dt(struct spi_device *spi,
62 struct tegra_spi_data *tspi)
63{
64 struct tegra_spi_device_controller_data *cdata;
65 struct device_node *slave_np, *data_np;
66
67 slave_np = spi->dev.of_node;
68 if (!slave_np) {
69 dev_dbg(&spi->dev, "device node not found\n");
70 return NULL;
71 }
72
73 data_np = of_get_child_by_name(slave_np, "controller-data");
74 if (!data_np) {
75 dev_dbg(&spi->dev, "child node 'controller-data' not found\n");
76 return NULL;
77 }
78
79 cdata = &tspi->cdata[spi->chip_select];
80 memset(cdata, 0, sizeof(*cdata));
81
82 of_property_read_u32(data_np, "nvidia,cs-setup-clk-count",
83 &cdata->cs_setup_clk_count);
84 of_property_read_u32(data_np, "nvidia,cs-hold-clk-count",
85 &cdata->cs_hold_clk_count);
86 of_property_read_u32(data_np, "nvidia,cs-inactive-cycles",
87 &cdata->cs_inactive_cycles);
88 of_node_put(data_np);
89
90 return cdata;
91}
92
93static void tegra_aon_spi_mbox_rcv_msg(struct mbox_client *cl, void *mssg)
94{
95 struct tegra_aon_mbox_msg *msg = mssg;
96 struct spi_master *master = dev_get_drvdata(cl->dev);
97 struct tegra_spi_data *tspi = spi_master_get_devdata(master);
98
99 memcpy(tspi->spi_resp, msg->data, sizeof(*tspi->spi_resp));
100 complete(tspi->xfer_completion);
101}
102
103static int ivc_aon_spi_send_req(struct tegra_spi_data *tspi, int len)
104{
105 int status;
106 struct tegra_aon_mbox_msg msg;
107
108 msg.length = len;
109 msg.data = (void *)tspi->spi_req;
110 status = mbox_send_message(tspi->mbox, (void *)&msg);
111 if (status < 0) {
112 dev_err(tspi->dev, "mbox_send_message() failed with %d\n",
113 status);
114 } else {
115 status = wait_for_completion_timeout(tspi->xfer_completion,
116 SPI_DMA_TIMEOUT);
117 if (status == 0) {
118 dev_err(tspi->dev, "Timeout waiting for ipc response\n");
119 return -ETIMEDOUT;
120 } else {
121 status = tspi->spi_resp->status;
122 }
123 }
124
125 return status;
126}
127
128static int do_ivc_aon_spi_init(struct tegra_spi_data *tspi)
129{
130 int len, status;
131
132 tspi->spi_req->req_type = AON_SPI_REQUEST_TYPE_INIT;
133 len = sizeof(tspi->spi_req->req_type);
134 status = ivc_aon_spi_send_req(tspi, len);
135 if (status)
136 return -EIO;
137
138 return 0;
139}
140
141static int do_ivc_aon_spi_setup(struct spi_device *spi,
142 struct tegra_spi_data *tspi)
143{
144 int status;
145 struct tegra_spi_device_controller_data *cdata = spi->controller_data;
146 struct aon_spi_request *req = tspi->spi_req;
147 int len;
148
149 dev_dbg(tspi->dev, "%s -> invocation\n", __func__);
150 req->req_type = AON_SPI_REQUEST_TYPE_SETUP;
151 if (cdata) {
152 req->data.setup.cs_setup_clk_count = cdata->cs_setup_clk_count;
153 req->data.setup.cs_hold_clk_count = cdata->cs_hold_clk_count;
154 req->data.setup.cs_inactive_cycles = cdata->cs_inactive_cycles;
155 }
156 req->data.setup.set_rx_tap_delay = tspi->chip_data->set_rx_tap_delay;
157 req->data.setup.chip_select = spi->chip_select;
158 spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency;
159 req->data.setup.spi_max_clk_rate = spi->max_speed_hz;
160 /* TODO: No-Dma support to be added for core driver */
161 req->data.setup.spi_no_dma = false;
162 len = (sizeof(req->req_type) + sizeof(struct aon_spi_setup_request));
163 status = ivc_aon_spi_send_req(tspi, len);
164 if (status)
165 return -EIO;
166
167 return 0;
168}
169
170#if defined(ENABLE_DUMPS)
171static void tegra_spi_dump_buf(u8 *buffer, int len, const char *name)
172{
173 int j;
174
175 pr_dbg("%s:::", name);
176 for (j = 0; j < len; j++)
177 pr_dbg("%x ", *(buffer + j));
178 pr_dbg("\n");
179}
180#else
181static void tegra_spi_dump_buf(u8 *buffer, int len, const char *name)
182{
183}
184#endif
185
186static int do_aon_ivc_spi_xfer(struct spi_device *spi,
187 struct spi_transfer *spi_xfer,
188 struct tegra_spi_data *tspi,
189 enum aon_spi_xfer_flag xfer_type)
190{
191 int length = 0, status = 0;
192 struct aon_spi_request *req = tspi->spi_req;
193 struct aon_spi_response *resp = tspi->spi_resp;
194
195 req->req_type = AON_SPI_REQUEST_TYPE_XFER;
196
197 req->data.xfer.xfers.flags = xfer_type;
198 if (spi_xfer->tx_buf)
199 req->data.xfer.xfers.flags |= AON_SPI_XFER_FLAG_WRITE;
200 if (spi_xfer->rx_buf)
201 req->data.xfer.xfers.flags |= AON_SPI_XFER_FLAG_READ;
202
203 req->data.xfer.xfers.length = spi_xfer->len;
204 req->data.xfer.xfers.rx_buf_offset = 0;
205 req->data.xfer.xfers.tx_buf_offset = 0;
206 req->data.xfer.xfers.chip_select = spi->chip_select;
207 req->data.xfer.xfers.tx_nbits = spi_xfer->tx_nbits;
208 req->data.xfer.xfers.rx_nbits = spi_xfer->rx_nbits;
209 req->data.xfer.xfers.bits_per_word = spi_xfer->bits_per_word;
210 req->data.xfer.xfers.mode = spi->mode;
211 req->data.xfer.xfers.spi_clk_rate = spi_xfer->speed_hz;
212 /* per-word bits-on-wire */
213
214 if (spi_xfer->tx_buf) {
215 memcpy(req->data.xfer.data, spi_xfer->tx_buf, spi_xfer->len);
216 tegra_spi_dump_buf(req->data.xfer.data, spi_xfer->len,
217 "reqdata");
218 }
219 /* alignmemt + data */
220 length = (TEGRA_IVC_ALIGN + spi_xfer->len + 1);
221 if (spi_xfer->len > AON_SPI_MAX_DATA_SIZE) {
222 dev_err(tspi->dev, "length %d greater than max length\n",
223 spi_xfer->len);
224 return -E2BIG;
225 }
226 status = ivc_aon_spi_send_req(tspi, length);
227 if (status) {
228 dev_err(tspi->dev, "Error in transfer\n");
229 return -EIO;
230 }
231 if (spi_xfer->rx_buf) {
232 memcpy(spi_xfer->rx_buf, resp->data.xfer.data, spi_xfer->len);
233 tegra_spi_dump_buf(spi_xfer->rx_buf, spi_xfer->len, "rxdata");
234 }
235
236 return 0;
237}
238
239static int tegra_spi_transfer_one_message(struct spi_master *master,
240 struct spi_message *msg)
241{
242 struct tegra_spi_data *tspi = spi_master_get_devdata(master);
243 struct spi_transfer *xfer;
244 int ret = -1;
245 int count = 0;
246 u16 flags = 0;
247
248 msg->status = 0;
249 msg->actual_length = 0;
250
251 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
252 flags |= AON_SPI_XFER_HANDLE_CACHE;
253 if (count == 0)
254 flags |= AON_SPI_XFER_FIRST_MSG;
255 if (list_is_last(&xfer->transfer_list, &msg->transfers))
256 flags |= AON_SPI_XFER_LAST_MSG;
257
258 ret = do_aon_ivc_spi_xfer(msg->spi, xfer, tspi, flags);
259 if (!ret)
260 msg->actual_length += xfer->len;
261 count++;
262 }
263
264 msg->status = ret;
265 spi_finalize_current_message(master);
266
267 return ret;
268}
269
270static int tegra_aon_spi_setup(struct spi_device *spi)
271{
272 int ret;
273 struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
274 struct tegra_spi_device_controller_data *cdata = spi->controller_data;
275
276 dev_dbg(tspi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n",
277 spi->bits_per_word,
278 spi->mode & SPI_CPOL ? "" : "~",
279 spi->mode & SPI_CPHA ? "" : "~",
280 spi->max_speed_hz);
281
282 if (!cdata) {
283 cdata = tegra_spi_get_cdata_dt(spi, tspi);
284 if (!cdata)
285 dev_err(&spi->dev, "Controller data not found\n");
286 else
287 spi->controller_data = cdata;
288 }
289
290 /* Set speed to the spi max fequency if spi device has not set */
291 spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency;
292
293 ret = do_ivc_aon_spi_setup(spi, tspi);
294 if (ret) {
295 dev_err(&spi->dev, "SPI aon client setup failed %d\n", ret);
296 ret = -EIO;
297 }
298
299 return ret;
300}
301
302static const struct tegra_aon_spi_chipdata tegra186_aon_spi_chipdata = {
303 .set_rx_tap_delay = false,
304};
305
306static const struct of_device_id tegra_aon_spi_of_match[] = {
307 {
308 .compatible = "nvidia,tegra186-aon-spi",
309 .data = &tegra186_aon_spi_chipdata,
310 },
311 {}
312};
313MODULE_DEVICE_TABLE(of, tegra_aon_spi_of_match);
314
315static int tegra_aon_spi_probe(struct platform_device *pdev)
316{
317 struct spi_master *master;
318 struct tegra_spi_data *tspi;
319 struct device_node *np = pdev->dev.of_node;
320 const unsigned int *prop;
321 const struct tegra_aon_spi_chipdata *chip_data = NULL;
322 int ret = 0;
323 int bus_num;
324
325 chip_data = of_device_get_match_data(&pdev->dev);
326 if (!chip_data) {
327 dev_err(&pdev->dev, "No platform/chip data, exiting\n");
328 return -ENODEV;
329 }
330 bus_num = of_alias_get_id(pdev->dev.of_node, "spi");
331 if (bus_num < 0) {
332 dev_warn(&pdev->dev,
333 "Dynamic bus number will be registerd\n");
334 bus_num = -1;
335 }
336
337 master = spi_alloc_master(&pdev->dev, sizeof(*tspi));
338 if (!master)
339 return -ENOMEM;
340
341 /* the spi->mode bits understood by this driver: */
342 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST |
343 SPI_TX_DUAL | SPI_RX_DUAL;
344 /* supported bpw 4-32 */
345 master->bits_per_word_mask = (u32) ~(BIT(0)|BIT(1)|BIT(2));
346 master->setup = tegra_aon_spi_setup;
347 master->transfer_one_message = tegra_spi_transfer_one_message;
348 master->num_chipselect = MAX_CHIP_SELECT;
349 master->bus_num = bus_num;
350
351 dev_set_drvdata(&pdev->dev, master);
352 tspi = spi_master_get_devdata(master);
353 tspi->master = master;
354 tspi->dev = &pdev->dev;
355 tspi->cl.dev = &pdev->dev;
356 tspi->cl.tx_block = true;
357 tspi->cl.tx_tout = TX_BLOCK_PERIOD;
358 tspi->cl.knows_txdone = false;
359 tspi->cl.rx_callback = tegra_aon_spi_mbox_rcv_msg;
360 tspi->mbox = mbox_request_channel(&tspi->cl, 0);
361 if (IS_ERR(tspi->mbox)) {
362 dev_warn(&pdev->dev,
363 "can't get mailbox channel (%d)\n",
364 (int)PTR_ERR(tspi->mbox));
365 ret = PTR_ERR(tspi->mbox);
366 goto exit_free_master;
367 }
368 dev_dbg(&pdev->dev, "tspi->mbox = %p\n", tspi->mbox);
369 tspi->def_chip_select = SPI_DEF_CHIPSELECT;
370 tspi->dev = &pdev->dev;
371 tspi->chip_data = chip_data;
372 tspi->xfer_completion = devm_kzalloc(&pdev->dev,
373 sizeof(struct completion), GFP_KERNEL);
374 if (!tspi->xfer_completion) {
375 ret = -ENOMEM;
376 goto exit_free_mbox;
377 }
378 init_completion(tspi->xfer_completion);
379
380 prop = of_get_property(np, "spi-max-frequency", NULL);
381 if (prop)
382 tspi->spi_max_frequency = be32_to_cpup(prop);
383 if (!tspi->spi_max_frequency) {
384 tspi->spi_max_frequency = SPI_DEFAULT_SPEED;
385 dev_dbg(&pdev->dev, "Max frequency set to %d\n",
386 SPI_DEFAULT_SPEED);
387 }
388
389 tspi->spi_req = devm_kzalloc(tspi->dev, sizeof(*tspi->spi_req),
390 GFP_KERNEL);
391 if (!tspi->spi_req) {
392 ret = -ENOMEM;
393 goto exit_free_mbox;
394 }
395 tspi->spi_resp = devm_kzalloc(tspi->dev, sizeof(*tspi->spi_resp),
396 GFP_KERNEL);
397 if (!tspi->spi_resp) {
398 ret = -ENOMEM;
399 goto exit_free_mbox;
400 }
401
402 ret = do_ivc_aon_spi_init(tspi);
403 if (ret) {
404 dev_err(&pdev->dev, "SPI aon init failed %d\n", ret);
405 ret = -EIO;
406 goto exit_free_mbox;
407 }
408 master->dev.of_node = pdev->dev.of_node;
409 ret = devm_spi_register_master(&pdev->dev, master);
410 if (ret < 0) {
411 dev_err(&pdev->dev, "can not register to master err %d\n", ret);
412 goto exit_free_mbox;
413 }
414 dev_dbg(&pdev->dev, "tegra_aon_spi_driver_probe() OK\n");
415
416 return ret;
417
418exit_free_mbox:
419 mbox_free_channel(tspi->mbox);
420exit_free_master:
421 spi_master_put(master);
422 dev_err(&pdev->dev, "tegra_aon_spi_driver_probe() FAILED\n");
423
424 return ret;
425}
426
427static int tegra_aon_spi_remove(struct platform_device *pdev)
428{
429 struct spi_master *master = dev_get_drvdata(&pdev->dev);
430 struct tegra_spi_data *tspi = spi_master_get_devdata(master);
431
432 mbox_free_channel(tspi->mbox);
433
434 return 0;
435}
436
437#ifdef CONFIG_PM_SLEEP
438static int tegra_aon_spi_suspend(struct device *dev)
439{
440 struct spi_master *master = dev_get_drvdata(dev);
441 struct tegra_spi_data *tspi = spi_master_get_devdata(master);
442 int len, ret, status;
443
444 ret = spi_master_suspend(master);
445 if (ret)
446 return ret;
447
448 tspi->spi_req->req_type = AON_SPI_REQUEST_TYPE_SUSPEND;
449 len = sizeof(tspi->spi_req->req_type);
450 status = ivc_aon_spi_send_req(tspi, len);
451 if (status)
452 return -EBUSY;
453
454 return 0;
455}
456
457static int tegra_aon_spi_resume(struct device *dev)
458{
459 struct spi_master *master = dev_get_drvdata(dev);
460 struct tegra_spi_data *tspi = spi_master_get_devdata(master);
461 int len, ret;
462
463 tspi->spi_req->req_type = AON_SPI_REQUEST_TYPE_RESUME;
464 len = sizeof(tspi->spi_req->req_type);
465 ret = ivc_aon_spi_send_req(tspi, len);
466 if (ret)
467 return -EIO;
468
469 return spi_master_resume(master);
470}
471#endif
472
473static const struct dev_pm_ops tegra_aon_spi_pm_ops = {
474 SET_SYSTEM_SLEEP_PM_OPS(tegra_aon_spi_suspend, tegra_aon_spi_resume)
475};
476
477static struct platform_driver tegra_aon_spi_driver = {
478 .driver = {
479 .name = "tegra-aon-spi",
480 .owner = THIS_MODULE,
481 .of_match_table = of_match_ptr(tegra_aon_spi_of_match),
482 .pm = &tegra_aon_spi_pm_ops,
483 },
484 .remove = tegra_aon_spi_remove,
485 .probe = tegra_aon_spi_probe,
486};
487module_platform_driver(tegra_aon_spi_driver);
488
489MODULE_DESCRIPTION("NVIDIA Tegra186 AON SPI Controller Driver");
490MODULE_LICENSE("GPL v2");