.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Altera Passive Serial SPI Driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2017 United Western Technologies, Corporation |
---|
5 | 6 | * |
---|
6 | 7 | * Joshua Clayton <stillcompiling@gmail.com> |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it |
---|
9 | | - * under the terms and conditions of the GNU General Public License, |
---|
10 | | - * version 2, as published by the Free Software Foundation. |
---|
11 | 8 | * |
---|
12 | 9 | * Manage Altera FPGA firmware that is loaded over SPI using the passive |
---|
13 | 10 | * serial configuration method. |
---|
.. | .. |
---|
73 | 70 | .status_wait_max_us = 3000, /* max(t_CF2ST1) */ |
---|
74 | 71 | .t_cfg_us = 2, /* max { min(t_CFG), max(tCF2ST0) } */ |
---|
75 | 72 | .t_st2ck_us = 10, /* min(t_ST2CK) */ |
---|
| 73 | +}; |
---|
| 74 | + |
---|
| 75 | +/* Array index is enum altera_ps_devtype */ |
---|
| 76 | +static const struct altera_ps_data *altera_ps_data_map[] = { |
---|
| 77 | + &c5_data, |
---|
| 78 | + &a10_data, |
---|
76 | 79 | }; |
---|
77 | 80 | |
---|
78 | 81 | static const struct of_device_id of_ef_match[] = { |
---|
.. | .. |
---|
199 | 202 | struct fpga_image_info *info) |
---|
200 | 203 | { |
---|
201 | 204 | struct altera_ps_conf *conf = mgr->priv; |
---|
202 | | - const char dummy[] = {0}; |
---|
| 205 | + static const char dummy[] = {0}; |
---|
203 | 206 | int ret; |
---|
204 | 207 | |
---|
205 | 208 | if (gpiod_get_value_cansleep(conf->status)) { |
---|
.. | .. |
---|
234 | 237 | .write_complete = altera_ps_write_complete, |
---|
235 | 238 | }; |
---|
236 | 239 | |
---|
| 240 | +static const struct altera_ps_data *id_to_data(const struct spi_device_id *id) |
---|
| 241 | +{ |
---|
| 242 | + kernel_ulong_t devtype = id->driver_data; |
---|
| 243 | + const struct altera_ps_data *data; |
---|
| 244 | + |
---|
| 245 | + /* someone added a altera_ps_devtype without adding to the map array */ |
---|
| 246 | + if (devtype >= ARRAY_SIZE(altera_ps_data_map)) |
---|
| 247 | + return NULL; |
---|
| 248 | + |
---|
| 249 | + data = altera_ps_data_map[devtype]; |
---|
| 250 | + if (!data || data->devtype != devtype) |
---|
| 251 | + return NULL; |
---|
| 252 | + |
---|
| 253 | + return data; |
---|
| 254 | +} |
---|
| 255 | + |
---|
237 | 256 | static int altera_ps_probe(struct spi_device *spi) |
---|
238 | 257 | { |
---|
239 | 258 | struct altera_ps_conf *conf; |
---|
240 | 259 | const struct of_device_id *of_id; |
---|
241 | 260 | struct fpga_manager *mgr; |
---|
242 | | - int ret; |
---|
243 | 261 | |
---|
244 | 262 | conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL); |
---|
245 | 263 | if (!conf) |
---|
246 | 264 | return -ENOMEM; |
---|
247 | 265 | |
---|
248 | | - of_id = of_match_device(of_ef_match, &spi->dev); |
---|
249 | | - if (!of_id) |
---|
250 | | - return -ENODEV; |
---|
| 266 | + if (spi->dev.of_node) { |
---|
| 267 | + of_id = of_match_device(of_ef_match, &spi->dev); |
---|
| 268 | + if (!of_id) |
---|
| 269 | + return -ENODEV; |
---|
| 270 | + conf->data = of_id->data; |
---|
| 271 | + } else { |
---|
| 272 | + conf->data = id_to_data(spi_get_device_id(spi)); |
---|
| 273 | + if (!conf->data) |
---|
| 274 | + return -ENODEV; |
---|
| 275 | + } |
---|
251 | 276 | |
---|
252 | | - conf->data = of_id->data; |
---|
253 | 277 | conf->spi = spi; |
---|
254 | 278 | conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_LOW); |
---|
255 | 279 | if (IS_ERR(conf->config)) { |
---|
.. | .. |
---|
278 | 302 | snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s %s", |
---|
279 | 303 | dev_driver_string(&spi->dev), dev_name(&spi->dev)); |
---|
280 | 304 | |
---|
281 | | - mgr = fpga_mgr_create(&spi->dev, conf->mgr_name, |
---|
282 | | - &altera_ps_ops, conf); |
---|
| 305 | + mgr = devm_fpga_mgr_create(&spi->dev, conf->mgr_name, |
---|
| 306 | + &altera_ps_ops, conf); |
---|
283 | 307 | if (!mgr) |
---|
284 | 308 | return -ENOMEM; |
---|
285 | 309 | |
---|
286 | 310 | spi_set_drvdata(spi, mgr); |
---|
287 | 311 | |
---|
288 | | - ret = fpga_mgr_register(mgr); |
---|
289 | | - if (ret) |
---|
290 | | - fpga_mgr_free(mgr); |
---|
291 | | - |
---|
292 | | - return ret; |
---|
| 312 | + return fpga_mgr_register(mgr); |
---|
293 | 313 | } |
---|
294 | 314 | |
---|
295 | 315 | static int altera_ps_remove(struct spi_device *spi) |
---|
.. | .. |
---|
302 | 322 | } |
---|
303 | 323 | |
---|
304 | 324 | static const struct spi_device_id altera_ps_spi_ids[] = { |
---|
305 | | - {"cyclone-ps-spi", 0}, |
---|
| 325 | + { "cyclone-ps-spi", CYCLONE5 }, |
---|
| 326 | + { "fpga-passive-serial", CYCLONE5 }, |
---|
| 327 | + { "fpga-arria10-passive-serial", ARRIA10 }, |
---|
306 | 328 | {} |
---|
307 | 329 | }; |
---|
308 | 330 | MODULE_DEVICE_TABLE(spi, altera_ps_spi_ids); |
---|