1 /* 2 * FPGA Manager Core 3 * 4 * Copyright (C) 2013-2015 Altera Corporation 5 * 6 * With code from the mailing list: 7 * Copyright (C) 2013 Xilinx, Inc. 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms and conditions of the GNU General Public License, 11 * version 2, as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 * more details. 17 * 18 * You should have received a copy of the GNU General Public License along with 19 * this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 #include <linux/firmware.h> 22 #include <linux/fpga/fpga-mgr.h> 23 #include <linux/idr.h> 24 #include <linux/module.h> 25 #include <linux/of.h> 26 #include <linux/mutex.h> 27 #include <linux/slab.h> 28 29 static DEFINE_IDA(fpga_mgr_ida); 30 static struct class *fpga_mgr_class; 31 32 /** 33 * fpga_mgr_buf_load - load fpga from image in buffer 34 * @mgr: fpga manager 35 * @flags: flags setting fpga confuration modes 36 * @buf: buffer contain fpga image 37 * @count: byte count of buf 38 * 39 * Step the low level fpga manager through the device-specific steps of getting 40 * an FPGA ready to be configured, writing the image to it, then doing whatever 41 * post-configuration steps necessary. This code assumes the caller got the 42 * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code. 43 * 44 * Return: 0 on success, negative error code otherwise. 45 */ 46 int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf, 47 size_t count) 48 { 49 struct device *dev = &mgr->dev; 50 int ret; 51 52 /* 53 * Call the low level driver's write_init function. This will do the 54 * device-specific things to get the FPGA into the state where it is 55 * ready to receive an FPGA image. 56 */ 57 mgr->state = FPGA_MGR_STATE_WRITE_INIT; 58 ret = mgr->mops->write_init(mgr, flags, buf, count); 59 if (ret) { 60 dev_err(dev, "Error preparing FPGA for writing\n"); 61 mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; 62 return ret; 63 } 64 65 /* 66 * Write the FPGA image to the FPGA. 67 */ 68 mgr->state = FPGA_MGR_STATE_WRITE; 69 ret = mgr->mops->write(mgr, buf, count); 70 if (ret) { 71 dev_err(dev, "Error while writing image data to FPGA\n"); 72 mgr->state = FPGA_MGR_STATE_WRITE_ERR; 73 return ret; 74 } 75 76 /* 77 * After all the FPGA image has been written, do the device specific 78 * steps to finish and set the FPGA into operating mode. 79 */ 80 mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE; 81 ret = mgr->mops->write_complete(mgr, flags); 82 if (ret) { 83 dev_err(dev, "Error after writing image data to FPGA\n"); 84 mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR; 85 return ret; 86 } 87 mgr->state = FPGA_MGR_STATE_OPERATING; 88 89 return 0; 90 } 91 EXPORT_SYMBOL_GPL(fpga_mgr_buf_load); 92 93 /** 94 * fpga_mgr_firmware_load - request firmware and load to fpga 95 * @mgr: fpga manager 96 * @flags: flags setting fpga confuration modes 97 * @image_name: name of image file on the firmware search path 98 * 99 * Request an FPGA image using the firmware class, then write out to the FPGA. 100 * Update the state before each step to provide info on what step failed if 101 * there is a failure. This code assumes the caller got the mgr pointer 102 * from of_fpga_mgr_get() and checked that it is not an error code. 103 * 104 * Return: 0 on success, negative error code otherwise. 105 */ 106 int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags, 107 const char *image_name) 108 { 109 struct device *dev = &mgr->dev; 110 const struct firmware *fw; 111 int ret; 112 113 dev_info(dev, "writing %s to %s\n", image_name, mgr->name); 114 115 mgr->state = FPGA_MGR_STATE_FIRMWARE_REQ; 116 117 ret = request_firmware(&fw, image_name, dev); 118 if (ret) { 119 mgr->state = FPGA_MGR_STATE_FIRMWARE_REQ_ERR; 120 dev_err(dev, "Error requesting firmware %s\n", image_name); 121 return ret; 122 } 123 124 ret = fpga_mgr_buf_load(mgr, flags, fw->data, fw->size); 125 126 release_firmware(fw); 127 128 return ret; 129 } 130 EXPORT_SYMBOL_GPL(fpga_mgr_firmware_load); 131 132 static const char * const state_str[] = { 133 [FPGA_MGR_STATE_UNKNOWN] = "unknown", 134 [FPGA_MGR_STATE_POWER_OFF] = "power off", 135 [FPGA_MGR_STATE_POWER_UP] = "power up", 136 [FPGA_MGR_STATE_RESET] = "reset", 137 138 /* requesting FPGA image from firmware */ 139 [FPGA_MGR_STATE_FIRMWARE_REQ] = "firmware request", 140 [FPGA_MGR_STATE_FIRMWARE_REQ_ERR] = "firmware request error", 141 142 /* Preparing FPGA to receive image */ 143 [FPGA_MGR_STATE_WRITE_INIT] = "write init", 144 [FPGA_MGR_STATE_WRITE_INIT_ERR] = "write init error", 145 146 /* Writing image to FPGA */ 147 [FPGA_MGR_STATE_WRITE] = "write", 148 [FPGA_MGR_STATE_WRITE_ERR] = "write error", 149 150 /* Finishing configuration after image has been written */ 151 [FPGA_MGR_STATE_WRITE_COMPLETE] = "write complete", 152 [FPGA_MGR_STATE_WRITE_COMPLETE_ERR] = "write complete error", 153 154 /* FPGA reports to be in normal operating mode */ 155 [FPGA_MGR_STATE_OPERATING] = "operating", 156 }; 157 158 static ssize_t name_show(struct device *dev, 159 struct device_attribute *attr, char *buf) 160 { 161 struct fpga_manager *mgr = to_fpga_manager(dev); 162 163 return sprintf(buf, "%s\n", mgr->name); 164 } 165 166 static ssize_t state_show(struct device *dev, 167 struct device_attribute *attr, char *buf) 168 { 169 struct fpga_manager *mgr = to_fpga_manager(dev); 170 171 return sprintf(buf, "%s\n", state_str[mgr->state]); 172 } 173 174 static DEVICE_ATTR_RO(name); 175 static DEVICE_ATTR_RO(state); 176 177 static struct attribute *fpga_mgr_attrs[] = { 178 &dev_attr_name.attr, 179 &dev_attr_state.attr, 180 NULL, 181 }; 182 ATTRIBUTE_GROUPS(fpga_mgr); 183 184 static int fpga_mgr_of_node_match(struct device *dev, const void *data) 185 { 186 return dev->of_node == data; 187 } 188 189 /** 190 * of_fpga_mgr_get - get an exclusive reference to a fpga mgr 191 * @node: device node 192 * 193 * Given a device node, get an exclusive reference to a fpga mgr. 194 * 195 * Return: fpga manager struct or IS_ERR() condition containing error code. 196 */ 197 struct fpga_manager *of_fpga_mgr_get(struct device_node *node) 198 { 199 struct fpga_manager *mgr; 200 struct device *dev; 201 int ret = -ENODEV; 202 203 dev = class_find_device(fpga_mgr_class, NULL, node, 204 fpga_mgr_of_node_match); 205 if (!dev) 206 return ERR_PTR(-ENODEV); 207 208 mgr = to_fpga_manager(dev); 209 if (!mgr) 210 goto err_dev; 211 212 /* Get exclusive use of fpga manager */ 213 if (!mutex_trylock(&mgr->ref_mutex)) { 214 ret = -EBUSY; 215 goto err_dev; 216 } 217 218 if (!try_module_get(dev->parent->driver->owner)) 219 goto err_ll_mod; 220 221 return mgr; 222 223 err_ll_mod: 224 mutex_unlock(&mgr->ref_mutex); 225 err_dev: 226 put_device(dev); 227 return ERR_PTR(ret); 228 } 229 EXPORT_SYMBOL_GPL(of_fpga_mgr_get); 230 231 /** 232 * fpga_mgr_put - release a reference to a fpga manager 233 * @mgr: fpga manager structure 234 */ 235 void fpga_mgr_put(struct fpga_manager *mgr) 236 { 237 module_put(mgr->dev.parent->driver->owner); 238 mutex_unlock(&mgr->ref_mutex); 239 put_device(&mgr->dev); 240 } 241 EXPORT_SYMBOL_GPL(fpga_mgr_put); 242 243 /** 244 * fpga_mgr_register - register a low level fpga manager driver 245 * @dev: fpga manager device from pdev 246 * @name: fpga manager name 247 * @mops: pointer to structure of fpga manager ops 248 * @priv: fpga manager private data 249 * 250 * Return: 0 on success, negative error code otherwise. 251 */ 252 int fpga_mgr_register(struct device *dev, const char *name, 253 const struct fpga_manager_ops *mops, 254 void *priv) 255 { 256 struct fpga_manager *mgr; 257 int id, ret; 258 259 if (!mops || !mops->write_init || !mops->write || 260 !mops->write_complete || !mops->state) { 261 dev_err(dev, "Attempt to register without fpga_manager_ops\n"); 262 return -EINVAL; 263 } 264 265 if (!name || !strlen(name)) { 266 dev_err(dev, "Attempt to register with no name!\n"); 267 return -EINVAL; 268 } 269 270 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 271 if (!mgr) 272 return -ENOMEM; 273 274 id = ida_simple_get(&fpga_mgr_ida, 0, 0, GFP_KERNEL); 275 if (id < 0) { 276 ret = id; 277 goto error_kfree; 278 } 279 280 mutex_init(&mgr->ref_mutex); 281 282 mgr->name = name; 283 mgr->mops = mops; 284 mgr->priv = priv; 285 286 /* 287 * Initialize framework state by requesting low level driver read state 288 * from device. FPGA may be in reset mode or may have been programmed 289 * by bootloader or EEPROM. 290 */ 291 mgr->state = mgr->mops->state(mgr); 292 293 device_initialize(&mgr->dev); 294 mgr->dev.class = fpga_mgr_class; 295 mgr->dev.parent = dev; 296 mgr->dev.of_node = dev->of_node; 297 mgr->dev.id = id; 298 dev_set_drvdata(dev, mgr); 299 300 ret = dev_set_name(&mgr->dev, "fpga%d", id); 301 if (ret) 302 goto error_device; 303 304 ret = device_add(&mgr->dev); 305 if (ret) 306 goto error_device; 307 308 dev_info(&mgr->dev, "%s registered\n", mgr->name); 309 310 return 0; 311 312 error_device: 313 ida_simple_remove(&fpga_mgr_ida, id); 314 error_kfree: 315 kfree(mgr); 316 317 return ret; 318 } 319 EXPORT_SYMBOL_GPL(fpga_mgr_register); 320 321 /** 322 * fpga_mgr_unregister - unregister a low level fpga manager driver 323 * @dev: fpga manager device from pdev 324 */ 325 void fpga_mgr_unregister(struct device *dev) 326 { 327 struct fpga_manager *mgr = dev_get_drvdata(dev); 328 329 dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name); 330 331 /* 332 * If the low level driver provides a method for putting fpga into 333 * a desired state upon unregister, do it. 334 */ 335 if (mgr->mops->fpga_remove) 336 mgr->mops->fpga_remove(mgr); 337 338 device_unregister(&mgr->dev); 339 } 340 EXPORT_SYMBOL_GPL(fpga_mgr_unregister); 341 342 static void fpga_mgr_dev_release(struct device *dev) 343 { 344 struct fpga_manager *mgr = to_fpga_manager(dev); 345 346 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); 347 kfree(mgr); 348 } 349 350 static int __init fpga_mgr_class_init(void) 351 { 352 pr_info("FPGA manager framework\n"); 353 354 fpga_mgr_class = class_create(THIS_MODULE, "fpga_manager"); 355 if (IS_ERR(fpga_mgr_class)) 356 return PTR_ERR(fpga_mgr_class); 357 358 fpga_mgr_class->dev_groups = fpga_mgr_groups; 359 fpga_mgr_class->dev_release = fpga_mgr_dev_release; 360 361 return 0; 362 } 363 364 static void __exit fpga_mgr_class_exit(void) 365 { 366 class_destroy(fpga_mgr_class); 367 ida_destroy(&fpga_mgr_ida); 368 } 369 370 MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 371 MODULE_DESCRIPTION("FPGA manager framework"); 372 MODULE_LICENSE("GPL v2"); 373 374 subsys_initcall(fpga_mgr_class_init); 375 module_exit(fpga_mgr_class_exit); 376