]> Git Repo - J-linux.git/blobdiff - drivers/fpga/fpga-mgr.c
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[J-linux.git] / drivers / fpga / fpga-mgr.c
index f38bab01432e2eae6a1bc7d7bd541837c488bcb0..ecb4c3c795fa561a6043efeee4ad481e163a4b6b 100644 (file)
 static DEFINE_IDA(fpga_mgr_ida);
 static struct class *fpga_mgr_class;
 
+struct fpga_mgr_devres {
+       struct fpga_manager *mgr;
+};
+
 /**
- * fpga_image_info_alloc - Allocate a FPGA image info struct
+ * fpga_image_info_alloc - Allocate an FPGA image info struct
  * @dev: owning device
  *
  * Return: struct fpga_image_info or NULL
@@ -46,7 +50,7 @@ struct fpga_image_info *fpga_image_info_alloc(struct device *dev)
 EXPORT_SYMBOL_GPL(fpga_image_info_alloc);
 
 /**
- * fpga_image_info_free - Free a FPGA image info struct
+ * fpga_image_info_free - Free an FPGA image info struct
  * @info: FPGA image info struct to free
  */
 void fpga_image_info_free(struct fpga_image_info *info)
@@ -466,7 +470,7 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data)
 }
 
 /**
- * fpga_mgr_get - Given a device, get a reference to a fpga mgr.
+ * fpga_mgr_get - Given a device, get a reference to an fpga mgr.
  * @dev:       parent device that fpga mgr was registered with
  *
  * Return: fpga manager struct or IS_ERR() condition containing error code.
@@ -483,7 +487,7 @@ struct fpga_manager *fpga_mgr_get(struct device *dev)
 EXPORT_SYMBOL_GPL(fpga_mgr_get);
 
 /**
- * of_fpga_mgr_get - Given a device node, get a reference to a fpga mgr.
+ * of_fpga_mgr_get - Given a device node, get a reference to an fpga mgr.
  *
  * @node:      device node
  *
@@ -502,7 +506,7 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
 EXPORT_SYMBOL_GPL(of_fpga_mgr_get);
 
 /**
- * fpga_mgr_put - release a reference to a fpga manager
+ * fpga_mgr_put - release a reference to an fpga manager
  * @mgr:       fpga manager structure
  */
 void fpga_mgr_put(struct fpga_manager *mgr)
@@ -546,8 +550,8 @@ void fpga_mgr_unlock(struct fpga_manager *mgr)
 EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
 
 /**
- * fpga_mgr_create - create and initialize a FPGA manager struct
- * @dev:       fpga manager device from pdev
+ * fpga_mgr_create - create and initialize an FPGA manager struct
+ * @parent:    fpga manager device from pdev
  * @name:      fpga manager name
  * @mops:      pointer to structure of fpga manager ops
  * @priv:      fpga manager private data
@@ -557,7 +561,7 @@ EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
  *
  * Return: pointer to struct fpga_manager or NULL
  */
-struct fpga_manager *fpga_mgr_create(struct device *dev, const char *name,
+struct fpga_manager *fpga_mgr_create(struct device *parent, const char *name,
                                     const struct fpga_manager_ops *mops,
                                     void *priv)
 {
@@ -567,12 +571,12 @@ struct fpga_manager *fpga_mgr_create(struct device *dev, const char *name,
        if (!mops || !mops->write_complete || !mops->state ||
            !mops->write_init || (!mops->write && !mops->write_sg) ||
            (mops->write && mops->write_sg)) {
-               dev_err(dev, "Attempt to register without fpga_manager_ops\n");
+               dev_err(parent, "Attempt to register without fpga_manager_ops\n");
                return NULL;
        }
 
        if (!name || !strlen(name)) {
-               dev_err(dev, "Attempt to register with no name!\n");
+               dev_err(parent, "Attempt to register with no name!\n");
                return NULL;
        }
 
@@ -593,8 +597,8 @@ struct fpga_manager *fpga_mgr_create(struct device *dev, const char *name,
        device_initialize(&mgr->dev);
        mgr->dev.class = fpga_mgr_class;
        mgr->dev.groups = mops->groups;
-       mgr->dev.parent = dev;
-       mgr->dev.of_node = dev->of_node;
+       mgr->dev.parent = parent;
+       mgr->dev.of_node = parent->of_node;
        mgr->dev.id = id;
 
        ret = dev_set_name(&mgr->dev, "fpga%d", id);
@@ -613,7 +617,7 @@ error_kfree:
 EXPORT_SYMBOL_GPL(fpga_mgr_create);
 
 /**
- * fpga_mgr_free - free a FPGA manager created with fpga_mgr_create()
+ * fpga_mgr_free - free an FPGA manager created with fpga_mgr_create()
  * @mgr:       fpga manager struct
  */
 void fpga_mgr_free(struct fpga_manager *mgr)
@@ -625,19 +629,19 @@ EXPORT_SYMBOL_GPL(fpga_mgr_free);
 
 static void devm_fpga_mgr_release(struct device *dev, void *res)
 {
-       struct fpga_manager *mgr = *(struct fpga_manager **)res;
+       struct fpga_mgr_devres *dr = res;
 
-       fpga_mgr_free(mgr);
+       fpga_mgr_free(dr->mgr);
 }
 
 /**
  * devm_fpga_mgr_create - create and initialize a managed FPGA manager struct
- * @dev:       fpga manager device from pdev
+ * @parent:    fpga manager device from pdev
  * @name:      fpga manager name
  * @mops:      pointer to structure of fpga manager ops
  * @priv:      fpga manager private data
  *
- * This function is intended for use in a FPGA manager driver's probe function.
+ * This function is intended for use in an FPGA manager driver's probe function.
  * After the manager driver creates the manager struct with
  * devm_fpga_mgr_create(), it should register it with fpga_mgr_register().  The
  * manager driver's remove function should call fpga_mgr_unregister().  The
@@ -647,30 +651,30 @@ static void devm_fpga_mgr_release(struct device *dev, void *res)
  *
  * Return: pointer to struct fpga_manager or NULL
  */
-struct fpga_manager *devm_fpga_mgr_create(struct device *dev, const char *name,
+struct fpga_manager *devm_fpga_mgr_create(struct device *parent, const char *name,
                                          const struct fpga_manager_ops *mops,
                                          void *priv)
 {
-       struct fpga_manager **ptr, *mgr;
+       struct fpga_mgr_devres *dr;
 
-       ptr = devres_alloc(devm_fpga_mgr_release, sizeof(*ptr), GFP_KERNEL);
-       if (!ptr)
+       dr = devres_alloc(devm_fpga_mgr_release, sizeof(*dr), GFP_KERNEL);
+       if (!dr)
                return NULL;
 
-       mgr = fpga_mgr_create(dev, name, mops, priv);
-       if (!mgr) {
-               devres_free(ptr);
-       } else {
-               *ptr = mgr;
-               devres_add(dev, ptr);
+       dr->mgr = fpga_mgr_create(parent, name, mops, priv);
+       if (!dr->mgr) {
+               devres_free(dr);
+               return NULL;
        }
 
-       return mgr;
+       devres_add(parent, dr);
+
+       return dr->mgr;
 }
 EXPORT_SYMBOL_GPL(devm_fpga_mgr_create);
 
 /**
- * fpga_mgr_register - register a FPGA manager
+ * fpga_mgr_register - register an FPGA manager
  * @mgr: fpga manager struct
  *
  * Return: 0 on success, negative error code otherwise.
@@ -702,10 +706,10 @@ error_device:
 EXPORT_SYMBOL_GPL(fpga_mgr_register);
 
 /**
- * fpga_mgr_unregister - unregister a FPGA manager
+ * fpga_mgr_unregister - unregister an FPGA manager
  * @mgr: fpga manager struct
  *
- * This function is intended for use in a FPGA manager driver's remove function.
+ * This function is intended for use in an FPGA manager driver's remove function.
  */
 void fpga_mgr_unregister(struct fpga_manager *mgr)
 {
@@ -722,6 +726,59 @@ void fpga_mgr_unregister(struct fpga_manager *mgr)
 }
 EXPORT_SYMBOL_GPL(fpga_mgr_unregister);
 
+static int fpga_mgr_devres_match(struct device *dev, void *res,
+                                void *match_data)
+{
+       struct fpga_mgr_devres *dr = res;
+
+       return match_data == dr->mgr;
+}
+
+static void devm_fpga_mgr_unregister(struct device *dev, void *res)
+{
+       struct fpga_mgr_devres *dr = res;
+
+       fpga_mgr_unregister(dr->mgr);
+}
+
+/**
+ * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()
+ * @dev: managing device for this FPGA manager
+ * @mgr: fpga manager struct
+ *
+ * This is the devres variant of fpga_mgr_register() for which the unregister
+ * function will be called automatically when the managing device is detached.
+ */
+int devm_fpga_mgr_register(struct device *dev, struct fpga_manager *mgr)
+{
+       struct fpga_mgr_devres *dr;
+       int ret;
+
+       /*
+        * Make sure that the struct fpga_manager * that is passed in is
+        * managed itself.
+        */
+       if (WARN_ON(!devres_find(dev, devm_fpga_mgr_release,
+                                fpga_mgr_devres_match, mgr)))
+               return -EINVAL;
+
+       dr = devres_alloc(devm_fpga_mgr_unregister, sizeof(*dr), GFP_KERNEL);
+       if (!dr)
+               return -ENOMEM;
+
+       ret = fpga_mgr_register(mgr);
+       if (ret) {
+               devres_free(dr);
+               return ret;
+       }
+
+       dr->mgr = mgr;
+       devres_add(dev, dr);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(devm_fpga_mgr_register);
+
 static void fpga_mgr_dev_release(struct device *dev)
 {
 }
This page took 0.040911 seconds and 4 git commands to generate.