5151
5252#include "pddf_client_defs.h"
5353#include "pddf_multifpgapci_defs.h"
54+ #include "pddf_multifpgapci_gpio_defs.h"
5455#include "pddf_multifpgapci_i2c_defs.h"
5556
5657#define BDF_NAME_SIZE 32
@@ -86,6 +87,9 @@ struct pddf_attrs {
8687 PDDF_ATTR attr_dev_ops ;
8788};
8889
90+ #define NUM_FPGA_ATTRS \
91+ (sizeof(struct pddf_attrs) / sizeof(PDDF_ATTR))
92+
8993struct pddf_multi_fpgapci_ops_t pddf_multi_fpgapci_ops ;
9094
9195EXPORT_SYMBOL (pddf_multi_fpgapci_ops );
@@ -95,10 +99,16 @@ struct fpga_data_node {
9599 char dev_name [DEVICE_NAME_SIZE ]; // device_name as defined in pddf-device.json.
96100 struct kobject * kobj ;
97101 struct pci_dev * dev ;
98- struct pddf_attrs attrs ;
99102 void __iomem * fpga_ctl_addr ;
100103 unsigned long bar_start ;
101104 struct list_head list ;
105+
106+ // sysfs attrs
107+ struct pddf_attrs attrs ;
108+ struct attribute * fpga_attrs [NUM_FPGA_ATTRS + 1 ];
109+ struct attribute_group fpga_attr_group ;
110+ bool fpga_attr_group_initialized ;
111+ bool pddf_clients_data_group_initialized ;
102112};
103113
104114LIST_HEAD (fpga_list );
@@ -165,12 +175,22 @@ void free_pci_drvdata(struct pci_dev *pci_dev)
165175 }
166176 KOBJ_FREE (pci_drvdata -> i2c_kobj );
167177
178+ if (pci_drvdata -> gpio_chip_drvdata_initialized ) {
179+ pddf_multifpgapci_gpio_module_exit (pci_dev ,
180+ pci_drvdata -> gpio_kobj );
181+ }
182+ KOBJ_FREE (pci_drvdata -> gpio_kobj );
183+
168184 pci_set_drvdata (pci_dev , NULL );
169185}
170186
171187void free_sysfs_attr_groups (struct fpga_data_node * node )
172188{
173- sysfs_remove_group (node -> kobj , & pddf_clients_data_group );
189+ if (node -> fpga_attr_group_initialized )
190+ sysfs_remove_group (node -> kobj , & node -> fpga_attr_group );
191+
192+ if (node -> pddf_clients_data_group_initialized )
193+ sysfs_remove_group (node -> kobj , & pddf_clients_data_group );
174194}
175195
176196void delete_fpga_data_node (const char * bdf )
@@ -181,11 +201,9 @@ void delete_fpga_data_node(const char *bdf)
181201
182202 list_for_each_entry_safe (node , tmp , & fpga_list , list ) {
183203 if (strcmp (node -> bdf , bdf ) == 0 ) {
184- KOBJ_FREE (node -> kobj );
185-
186204 free_pci_drvdata (node -> dev );
187205 free_sysfs_attr_groups (node );
188-
206+ KOBJ_FREE ( node -> kobj );
189207 list_del (& node -> list );
190208 kfree (node );
191209 break ;
@@ -290,6 +308,23 @@ static int pddf_pci_add_fpga(char *bdf, struct pci_dev *dev)
290308 }
291309 pci_drvdata -> i2c_adapter_drvdata_initialized = true;
292310
311+ pci_drvdata -> gpio_kobj = kobject_create_and_add ("gpio" , fpga_data -> kobj );
312+ if (!pci_drvdata -> gpio_kobj ) {
313+ pddf_dbg (MULTIFPGA , KERN_ERR "%s create gpio kobj failed\n" ,
314+ __FUNCTION__ );
315+ ret = - ENOMEM ;
316+ goto free_i2c_dirs ;
317+ }
318+
319+ ret = pddf_multifpgapci_gpio_module_init (dev , pci_drvdata -> gpio_kobj );
320+ if (ret ) {
321+ pddf_dbg (MULTIFPGA ,
322+ KERN_ERR "%s create add gpio module failed %d\n" ,
323+ __FUNCTION__ , ret );
324+ goto free_gpio_kobj ;
325+ }
326+ pci_drvdata -> gpio_chip_drvdata_initialized = true;
327+
293328 fpga_data -> dev = dev ;
294329
295330 PDDF_DATA_ATTR (
@@ -298,40 +333,50 @@ static int pddf_pci_add_fpga(char *bdf, struct pci_dev *dev)
298333
299334 fpga_data -> attrs .attr_dev_ops = attr_dev_ops ;
300335
301- struct attribute * attrs_fpgapci [] = {
302- & fpga_data -> attrs .attr_dev_ops .dev_attr .attr ,
303- NULL ,
304- };
336+ fpga_data -> fpga_attrs [0 ] = & fpga_data -> attrs .attr_dev_ops .dev_attr .attr ;
337+ fpga_data -> fpga_attrs [1 ] = NULL ;
305338
306- struct attribute_group attr_group_fpgapci = {
307- .attrs = attrs_fpgapci ,
308- };
309-
310- mutex_lock (& fpga_list_lock );
311- list_add (& fpga_data -> list , & fpga_list );
312- mutex_unlock (& fpga_list_lock );
339+ fpga_data -> fpga_attr_group .attrs = fpga_data -> fpga_attrs ;
313340
314- ret = sysfs_create_group (fpga_data -> kobj , & attr_group_fpgapci );
341+ ret = sysfs_create_group (fpga_data -> kobj , & fpga_data -> fpga_attr_group );
315342
316343 if (ret ) {
317344 pddf_dbg (MULTIFPGA ,
318345 KERN_ERR "%s create fpga sysfs attributes failed\n" ,
319346 __FUNCTION__ );
320- return ret ;
347+ goto free_gpio_dirs ;
321348 }
349+ fpga_data -> fpga_attr_group_initialized = true;
322350
323351 ret = sysfs_create_group (fpga_data -> kobj , & pddf_clients_data_group );
324352 if (ret ) {
325353 pddf_dbg (MULTIFPGA ,
326- KERN_ERR "[%s] sysfs_create_group failed: %d\n" ,
354+ KERN_ERR "[%s] create pddf_clients_data_group failed: %d\n" ,
327355 __FUNCTION__ , ret );
328356 goto free_fpga_attr_group ;
329357 }
358+ fpga_data -> pddf_clients_data_group_initialized = true;
359+
360+ mutex_lock (& fpga_list_lock );
361+ list_add (& fpga_data -> list , & fpga_list );
362+ mutex_unlock (& fpga_list_lock );
330363
331364 return 0 ;
332365
333366free_fpga_attr_group :
334- sysfs_remove_group (fpga_data -> kobj , & attr_group_fpgapci );
367+ fpga_data -> fpga_attr_group_initialized = false;
368+ sysfs_remove_group (fpga_data -> kobj , & fpga_data -> fpga_attr_group );
369+
370+ free_gpio_dirs :
371+ pci_drvdata -> gpio_chip_drvdata_initialized = false;
372+ pddf_multifpgapci_gpio_module_exit (dev , pci_drvdata -> gpio_kobj );
373+
374+ free_gpio_kobj :
375+ kobject_put (pci_drvdata -> gpio_kobj );
376+
377+ free_i2c_dirs :
378+ pci_drvdata -> i2c_adapter_drvdata_initialized = false;
379+ pddf_multifpgapci_i2c_module_exit (dev , pci_drvdata -> i2c_kobj );
335380
336381free_i2c_kobj :
337382 kobject_put (pci_drvdata -> i2c_kobj );
@@ -571,7 +616,7 @@ static int pddf_multifpgapci_probe(struct pci_dev *dev,
571616 KERN_ERR
572617 "[%s] pci_enable_device failed. dev:%s err:%#x\n" ,
573618 __FUNCTION__ , pci_name (dev ), err );
574- return err ;
619+ goto error_enable_dev ;
575620 }
576621
577622 // Enable DMA
@@ -595,6 +640,7 @@ static int pddf_multifpgapci_probe(struct pci_dev *dev,
595640 KERN_ERR
596641 "[%s] couldn't allocate pci_privdata memory\n" ,
597642 __FUNCTION__ );
643+ err = - ENOMEM ;
598644 goto error_pci_req ;
599645 }
600646
@@ -605,10 +651,10 @@ static int pddf_multifpgapci_probe(struct pci_dev *dev,
605651
606652 return 0 ;
607653
608- // ERROR HANDLING
609654error_pci_req :
610655 pci_disable_device (dev );
611- return - ENODEV ;
656+ error_enable_dev :
657+ return err ;
612658}
613659
614660// Initialize the driver module (but not any device) and register
0 commit comments