Browse Source

modify driver mode

宋超 3 years ago
parent
commit
6db57a0117
4 changed files with 161 additions and 98 deletions
  1. 1 2
      include/rt_driver.h
  2. 6 2
      include/rtthread.h
  3. 92 0
      src/device.c
  4. 62 94
      src/driver.c

+ 1 - 2
include/rt_driver.h

@@ -13,7 +13,6 @@ struct rt_device_id
 
 struct rt_driver
 {
-    struct rt_object parent;
 #ifdef RT_USING_DEVICE_OPS    
     const struct rt_device_ops *dev_ops;
 #endif    
@@ -23,10 +22,10 @@ struct rt_driver
     int device_priv_data_size;
     int device_size;
     int flag;
-    int total_device_num;
     const struct rt_device_id *dev_match;
 	int (*probe)(struct rt_device *dev);
     int (*init)(struct rt_device *dev);
+    int (*remove)(struct rt_device *dev);
 	const void *ops;	/* driver-specific operations */
 };
 typedef struct rt_driver *rt_driver_t;

+ 6 - 2
include/rtthread.h

@@ -518,8 +518,12 @@ rt_size_t rt_device_write(rt_device_t dev,
                           rt_size_t   size);
 rt_err_t  rt_device_control(rt_device_t dev, int cmd, void *arg);
 
-rt_err_t rt_driver_register(rt_driver_t drv);
-rt_err_t rt_driver_unregister(rt_driver_t drv);
+rt_err_t rt_device_driver_bind(rt_device_t device, rt_driver_t driver, void *node);
+rt_device_t rt_device_create_since_driver(rt_driver_t drv,int device_id);
+rt_err_t rt_device_probe_and_init(rt_device_t device);
+rt_err_t rt_driver_device_match_with_id(const rt_driver_t drv,int device_id);
+rt_err_t rt_driver_device_match_with_dtb(const rt_driver_t drv,void *from_node,int max_dev_num);
+rt_err_t rt_driver_unregister(const rt_driver_t drv);
 
 /**@}*/
 #endif

+ 92 - 0
src/device.c

@@ -477,4 +477,96 @@ rt_device_set_tx_complete(rt_device_t dev,
 }
 RTM_EXPORT(rt_device_set_tx_complete);
 
+/**
+ * This function  bind drvier and device
+ *
+ * @param driver the pointer of driver structure
+ * @param device the pointer of device structure
+ * @param node the pointer of fdt node structure
+ *
+ * @return the error code, RT_EOK on successfully.
+ */
+rt_err_t rt_device_driver_bind(rt_device_t device, rt_driver_t driver, void *node)
+{
+    if((!driver) || (!device))
+    {
+        return -RT_EINVAL;
+    }
+
+    device->drv = driver;
+#ifdef RT_USING_DEVICE_OPS    
+    device->ops = driver->dev_ops;
+#endif    
+    device->fdt_node = node;
+
+    return RT_EOK;
+} 
+RTM_EXPORT(rt_device_driver_bind);
+
+/**
+ * This function  create rt_device according to driver infomation
+ *
+ * @param drv the pointer of driver structure
+ * @param device_id specify the ID of the rt_device
+ *
+ * @return the error code, RT_EOK on successfully.
+ */
+rt_device_t rt_device_create_since_driver(rt_driver_t drv,int device_id)
+{
+    rt_device_t device;
+    if (!drv)
+    {
+        return RT_NULL;
+    }
+
+    device = (rt_device_t)rt_calloc(1,drv->device_size);
+    if(device == RT_NULL)
+    {
+        return RT_NULL;
+    }
+    if(drv->device_priv_data_size != 0)
+    {
+        device->user_data = (void *)(rt_calloc(1,drv->device_priv_data_size));
+        if(device->user_data == RT_NULL)
+        {
+            rt_free(device);
+            return RT_NULL;
+        }   
+    }
+
+    device->device_id = device_id;
+    rt_snprintf(device->parent.name, sizeof(device->parent.name), "%s%d", drv->name, device_id);
+    return device;
+}
+RTM_EXPORT(rt_device_create_since_driver);
+
+/**
+ * This function  rt_device probe and init
+ *
+ * @param device the pointer of rt_device structure
+ * @return the error code, RT_EOK on successfully.
+ */
+rt_err_t rt_device_probe_and_init(rt_device_t device)
+{
+    int ret = -RT_ERROR;
+    if (!device)
+    {
+        return -RT_EINVAL;
+    }
+    if(!device->drv)
+    {
+        return -RT_ERROR;
+    }
+    if(device->drv->probe)
+    {
+        ret = device->drv->probe((rt_device_t)device);
+    }
+    if(device->drv->init)
+    {
+        ret = device->drv->init((rt_device_t)device);
+    }
+    return ret;
+}
+RTM_EXPORT(rt_device_probe_and_init);
+
 #endif

+ 62 - 94
src/driver.c

@@ -6,137 +6,105 @@
 
 #include <rtthread.h>
 #include <fdt.h>
-#include <rt_dtb_node.h>
-#include <rt_device_node.h>
 #if defined(RT_USING_POSIX)
 #include <rtdevice.h> /* for wqueue_init */
 #endif
 
-#define MAX_COMPATIBLE_NUM 10
-
 /**
- * This function  bind drvier and device
+ * This function registers a device driver with specified name.
  *
- * @param driver the pointer of driver structure
- * @param device the pointer of device structure
- * @param node the pointer of fdt node structure
+ * @param drv the pointer of driver structure
+ * @param device_id the id of the device
  *
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_device_bind(rt_driver_t driver, rt_device_t device, void *node)
+rt_err_t rt_driver_device_match_with_id(const rt_driver_t drv,int device_id)
 {
-    if((!driver) || (!device))
+    rt_device_t device;
+    int ret;
+    if (!drv)
+    {
+        return -RT_EINVAL;
+    }
+    device = rt_device_create_since_driver(drv,device_id);
+    if(!device)
     {
         return -RT_ERROR;
     }
+    ret = rt_device_driver_bind(device,drv,RT_NULL);
+    if(ret != 0)
+    {
+        return -RT_ERROR;
+    }
+    ret = rt_device_probe_and_init(device);
+    if(ret != 0)
+    {
+        return -RT_ERROR;
+    }
+    return ret;
+}
 
-    device->drv = driver;
-#ifdef RT_USING_DEVICE_OPS    
-    device->ops = driver->dev_ops;
-#endif    
-    device->fdt_node = node;
-
-    return RT_EOK;
-} 
+RTM_EXPORT(rt_driver_device_match_with_id);
 
+#ifdef PKG_USING_FDT
 /**
- * This function  create rt_device and init the device
- *
- * @param driver the pointer of driver structure
- * @param device_num how many device should be create
- * @param ftd_node_list ftd node list
+ * This function registers a device driver with specified name.
  *
+ * @param drv the pointer of driver structure
+ * @param from_node eth entry ftd node 
+ * @param max_dev_num the max device support 
+ * 
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_device_create_and_init(rt_driver_t drv,int device_num,struct dtb_node **ftd_node_list)
+rt_err_t rt_driver_device_match_with_dtb(const rt_driver_t drv,void *from_node,int max_dev_num)
 {
-    int i = 0;
-    int ret = -1;
+    struct dtb_node** node_list; 
     rt_device_t device;
-    for(i = 0; i < device_num; i ++)
+    int ret,i;
+    int active_dev_num = 0;
+    if ((!drv)||(!drv->dev_match)||(!drv->dev_match->compatible)||(!from_node))
     {
-        device = (rt_device_t)rt_malloc(drv->device_size);
-        if(device == RT_NULL)
-        {
-            return -RT_ERROR;
-        }
-        rt_memset(device,0,drv->device_size);
-        if(drv->device_priv_data_size != 0)
-        {
-            device->user_data = (void *)(rt_malloc(drv->device_priv_data_size));
-            if(device->user_data == RT_NULL)
-            {
-                rt_free(device);
-                return -RT_ERROR;
-            }   
-            rt_memset(device->user_data,0,drv->device_priv_data_size);
-        }
-        
-        device->device_id = i;
-        rt_strncpy(device->parent.name,drv->name,rt_strlen(drv->name));
-        rt_sprintf(device->parent.name + rt_strlen(drv->name),"%d",i);
-
-        rt_device_bind(drv,device,ftd_node_list[i]);
-
-        if(device->drv->probe)
-        {
-            ret = device->drv->probe((rt_device_t)device);
-        }
-        if(device->drv->init)
-        {
-            ret = device->drv->init((rt_device_t)device);
-        }
+        return -RT_EINVAL;
+    }
 
+    node_list = rt_calloc(max_dev_num,sizeof(void *));
+    if(!node_list)
+    {
+        return -RT_ERROR;
     }
-    return ret;
-}
-/**
- * This function registers a device driver with specified name.
- *
- * @param dev the pointer of driver structure
- * @param flags the capabilities flag of device
- *
- * @return the error code, RT_EOK on successfully.
- */
-rt_err_t rt_driver_register(rt_driver_t drv)
-{
-    struct dtb_node *root_node = RT_NULL;
-    struct dtb_node* node_list[MAX_COMPATIBLE_NUM]; 
-    int ret,i,device_num;
-    if (drv == RT_NULL)
+    
+    ret = fdt_find_all_active_compatible_node(from_node,drv->dev_match->compatible,node_list,max_dev_num,&active_dev_num);
+    if((ret != 0) || (!active_dev_num))
     {
         return -RT_ERROR;
     }
-
-    root_node = get_dtb_node_head();
-    if(drv->dev_match->compatible != RT_NULL)
+    
+    for(i = 0; i < active_dev_num; i ++)
     {
-#ifdef PKG_USING_FDT        
-        ret = fdt_find_all_active_compatible_node(root_node,drv->dev_match->compatible,node_list,MAX_COMPATIBLE_NUM,&device_num);
-        if(!ret)
+        device = rt_device_create_since_driver(drv,i);
+        if(!device)
         {
+            return -RT_ERROR;
         }
-#endif        
-    }
-    else
-    {
-        device_num = drv->total_device_num;  
-        for(i = 0; i < device_num; i++)
+    
+        ret = rt_device_driver_bind(device,drv,node_list[i]);
+        if(ret != 0)
         {
-            node_list[i] = RT_NULL;
+            return -RT_ERROR;
+        }
+        ret = rt_device_probe_and_init(device);
+        if(ret != 0)
+        {
+            return -RT_ERROR;
         }
-    }
 
-    if(!device_num)
-    {
-        rt_kprintf("can not match compatible device\n");
     }
-    ret = rt_device_create_and_init(drv,device_num,node_list);
 
     return ret;
 }
 
-RTM_EXPORT(rt_driver_register);
+RTM_EXPORT(rt_driver_device_match_with_dtb);
+#endif  
 
 /**
  * This function removes a previously registered device driver
@@ -145,7 +113,7 @@ RTM_EXPORT(rt_driver_register);
  *
  * @return the error code, RT_EOK on successfully.
  */
-rt_err_t rt_driver_unregister(rt_driver_t drv)
+rt_err_t rt_driver_unregister(const rt_driver_t drv)
 {
     /*todo*/
     return RT_EOK;