1414#include <linux/export.h>
1515#include <linux/gpio/driver.h>
1616#include <linux/gpio/machine.h>
17+ #include <linux/gpio/property.h>
1718#include <linux/idr.h>
1819#include <linux/kernel.h>
1920#include <linux/kref.h>
@@ -77,10 +78,12 @@ struct reset_control_array {
7778/**
7879 * struct reset_gpio_lookup - lookup key for ad-hoc created reset-gpio devices
7980 * @of_args: phandle to the reset controller with all the args like GPIO number
81+ * @swnode: Software node containing the reference to the GPIO provider
8082 * @list: list entry for the reset_gpio_lookup_list
8183 */
8284struct reset_gpio_lookup {
8385 struct of_phandle_args of_args ;
86+ struct fwnode_handle * swnode ;
8487 struct list_head list ;
8588};
8689
@@ -849,61 +852,56 @@ static void __reset_control_put_internal(struct reset_control *rstc)
849852 kref_put (& rstc -> refcnt , __reset_control_release );
850853}
851854
852- static int __reset_add_reset_gpio_lookup (struct gpio_device * gdev , int id ,
853- struct device_node * np ,
854- unsigned int gpio ,
855- unsigned int of_flags )
855+ static void reset_gpio_aux_device_release (struct device * dev )
856856{
857- unsigned int lookup_flags ;
858- const char * label_tmp ;
857+ struct auxiliary_device * adev = to_auxiliary_dev (dev );
859858
860- /*
861- * Later we map GPIO flags between OF and Linux, however not all
862- * constants from include/dt-bindings/gpio/gpio.h and
863- * include/linux/gpio/machine.h match each other.
864- */
865- if (of_flags > GPIO_ACTIVE_LOW ) {
866- pr_err ("reset-gpio code does not support GPIO flags %u for GPIO %u\n" ,
867- of_flags , gpio );
868- return - EINVAL ;
869- }
870-
871- label_tmp = gpio_device_get_label (gdev );
872- if (!label_tmp )
873- return - EINVAL ;
859+ kfree (adev );
860+ }
874861
875- char * label __free (kfree ) = kstrdup (label_tmp , GFP_KERNEL );
876- if (!label )
877- return - ENOMEM ;
862+ static int reset_add_gpio_aux_device (struct device * parent ,
863+ struct fwnode_handle * swnode ,
864+ int id , void * pdata )
865+ {
866+ struct auxiliary_device * adev ;
867+ int ret ;
878868
879- /* Size: one lookup entry plus sentinel */
880- struct gpiod_lookup_table * lookup __free (kfree ) = kzalloc (struct_size (lookup , table , 2 ),
881- GFP_KERNEL );
882- if (!lookup )
869+ adev = kzalloc (sizeof (* adev ), GFP_KERNEL );
870+ if (!adev )
883871 return - ENOMEM ;
884872
885- lookup -> dev_id = kasprintf (GFP_KERNEL , "reset.gpio.%d" , id );
886- if (!lookup -> dev_id )
887- return - ENOMEM ;
873+ adev -> id = id ;
874+ adev -> name = "gpio" ;
875+ adev -> dev .parent = parent ;
876+ adev -> dev .platform_data = pdata ;
877+ adev -> dev .release = reset_gpio_aux_device_release ;
878+ device_set_node (& adev -> dev , swnode );
888879
889- lookup_flags = GPIO_PERSISTENT ;
890- lookup_flags |= of_flags & GPIO_ACTIVE_LOW ;
891- lookup -> table [0 ] = GPIO_LOOKUP (no_free_ptr (label ), gpio , "reset" ,
892- lookup_flags );
880+ ret = auxiliary_device_init (adev );
881+ if (ret ) {
882+ kfree (adev );
883+ return ret ;
884+ }
893885
894- /* Not freed on success, because it is persisent subsystem data. */
895- gpiod_add_lookup_table (no_free_ptr (lookup ));
886+ ret = __auxiliary_device_add (adev , "reset" );
887+ if (ret ) {
888+ auxiliary_device_uninit (adev );
889+ kfree (adev );
890+ return ret ;
891+ }
896892
897- return 0 ;
893+ return ret ;
898894}
899895
900896/*
901897 * @args: phandle to the GPIO provider with all the args like GPIO number
902898 */
903899static int __reset_add_reset_gpio_device (const struct of_phandle_args * args )
904900{
901+ struct property_entry properties [2 ] = { };
902+ unsigned int offset , of_flags , lflags ;
905903 struct reset_gpio_lookup * rgpio_dev ;
906- struct auxiliary_device * adev ;
904+ struct device * parent ;
907905 int id , ret ;
908906
909907 /*
@@ -922,6 +920,23 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
922920 */
923921 lockdep_assert_not_held (& reset_list_mutex );
924922
923+ offset = args -> args [0 ];
924+ of_flags = args -> args [1 ];
925+
926+ /*
927+ * Later we map GPIO flags between OF and Linux, however not all
928+ * constants from include/dt-bindings/gpio/gpio.h and
929+ * include/linux/gpio/machine.h match each other.
930+ *
931+ * FIXME: Find a better way of translating OF flags to GPIO lookup
932+ * flags.
933+ */
934+ if (of_flags > GPIO_ACTIVE_LOW ) {
935+ pr_err ("reset-gpio code does not support GPIO flags %u for GPIO %u\n" ,
936+ of_flags , offset );
937+ return - EINVAL ;
938+ }
939+
925940 struct gpio_device * gdev __free (gpio_device_put ) =
926941 gpio_device_find_by_fwnode (of_fwnode_handle (args -> np ));
927942 if (!gdev )
@@ -936,6 +951,10 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
936951 }
937952 }
938953
954+ lflags = GPIO_PERSISTENT | (of_flags & GPIO_ACTIVE_LOW );
955+ parent = gpio_device_to_device (gdev );
956+ properties [0 ] = PROPERTY_ENTRY_GPIO ("reset-gpios" , parent -> fwnode , offset , lflags );
957+
939958 id = ida_alloc (& reset_gpio_ida , GFP_KERNEL );
940959 if (id < 0 )
941960 return id ;
@@ -947,31 +966,33 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
947966 goto err_ida_free ;
948967 }
949968
950- ret = __reset_add_reset_gpio_lookup (gdev , id , args -> np , args -> args [0 ],
951- args -> args [1 ]);
952- if (ret < 0 )
953- goto err_kfree ;
954-
955969 rgpio_dev -> of_args = * args ;
956970 /*
957971 * We keep the device_node reference, but of_args.np is put at the end
958972 * of __of_reset_control_get(), so get it one more time.
959973 * Hold reference as long as rgpio_dev memory is valid.
960974 */
961975 of_node_get (rgpio_dev -> of_args .np );
962- adev = auxiliary_device_create (gpio_device_to_device (gdev ), "reset" ,
963- "gpio" , & rgpio_dev -> of_args , id );
964- ret = PTR_ERR_OR_ZERO (adev );
976+
977+ rgpio_dev -> swnode = fwnode_create_software_node (properties , NULL );
978+ if (IS_ERR (rgpio_dev -> swnode )) {
979+ ret = PTR_ERR (rgpio_dev -> swnode );
980+ goto err_put_of_node ;
981+ }
982+
983+ ret = reset_add_gpio_aux_device (parent , rgpio_dev -> swnode , id ,
984+ & rgpio_dev -> of_args );
965985 if (ret )
966- goto err_put ;
986+ goto err_del_swnode ;
967987
968988 list_add (& rgpio_dev -> list , & reset_gpio_lookup_list );
969989
970990 return 0 ;
971991
972- err_put :
992+ err_del_swnode :
993+ fwnode_remove_software_node (rgpio_dev -> swnode );
994+ err_put_of_node :
973995 of_node_put (rgpio_dev -> of_args .np );
974- err_kfree :
975996 kfree (rgpio_dev );
976997err_ida_free :
977998 ida_free (& reset_gpio_ida , id );
0 commit comments