1212#include <linux/slab.h>
1313#include <linux/spinlock.h>
1414#include <linux/platform_device.h>
15- #include <linux/gpio.h>
16- #include <linux/of_gpio.h>
15+ #include <linux/gpio/consumer.h>
1716#include <linux/leds.h>
17+ #include <linux/of.h>
18+ #include <linux/of_platform.h>
1819
1920struct netxbig_gpio_ext {
20- unsigned int * addr ;
21+ struct gpio_desc * * addr ;
2122 int num_addr ;
22- unsigned int * data ;
23+ struct gpio_desc * * data ;
2324 int num_data ;
24- unsigned int enable ;
25+ struct gpio_desc * enable ;
2526};
2627
2728enum netxbig_led_mode {
@@ -69,22 +70,22 @@ static void gpio_ext_set_addr(struct netxbig_gpio_ext *gpio_ext, int addr)
6970 int pin ;
7071
7172 for (pin = 0 ; pin < gpio_ext -> num_addr ; pin ++ )
72- gpio_set_value (gpio_ext -> addr [pin ], (addr >> pin ) & 1 );
73+ gpiod_set_value (gpio_ext -> addr [pin ], (addr >> pin ) & 1 );
7374}
7475
7576static void gpio_ext_set_data (struct netxbig_gpio_ext * gpio_ext , int data )
7677{
7778 int pin ;
7879
7980 for (pin = 0 ; pin < gpio_ext -> num_data ; pin ++ )
80- gpio_set_value (gpio_ext -> data [pin ], (data >> pin ) & 1 );
81+ gpiod_set_value (gpio_ext -> data [pin ], (data >> pin ) & 1 );
8182}
8283
8384static void gpio_ext_enable_select (struct netxbig_gpio_ext * gpio_ext )
8485{
8586 /* Enable select is done on the raising edge. */
86- gpio_set_value (gpio_ext -> enable , 0 );
87- gpio_set_value (gpio_ext -> enable , 1 );
87+ gpiod_set_value (gpio_ext -> enable , 0 );
88+ gpiod_set_value (gpio_ext -> enable , 1 );
8889}
8990
9091static void gpio_ext_set_value (struct netxbig_gpio_ext * gpio_ext ,
@@ -99,41 +100,6 @@ static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext,
99100 spin_unlock_irqrestore (& gpio_ext_lock , flags );
100101}
101102
102- static int gpio_ext_init (struct platform_device * pdev ,
103- struct netxbig_gpio_ext * gpio_ext )
104- {
105- int err ;
106- int i ;
107-
108- if (unlikely (!gpio_ext ))
109- return - EINVAL ;
110-
111- /* Configure address GPIOs. */
112- for (i = 0 ; i < gpio_ext -> num_addr ; i ++ ) {
113- err = devm_gpio_request_one (& pdev -> dev , gpio_ext -> addr [i ],
114- GPIOF_OUT_INIT_LOW ,
115- "GPIO extension addr" );
116- if (err )
117- return err ;
118- }
119- /* Configure data GPIOs. */
120- for (i = 0 ; i < gpio_ext -> num_data ; i ++ ) {
121- err = devm_gpio_request_one (& pdev -> dev , gpio_ext -> data [i ],
122- GPIOF_OUT_INIT_LOW ,
123- "GPIO extension data" );
124- if (err )
125- return err ;
126- }
127- /* Configure "enable select" GPIO. */
128- err = devm_gpio_request_one (& pdev -> dev , gpio_ext -> enable ,
129- GPIOF_OUT_INIT_LOW ,
130- "GPIO extension enable" );
131- if (err )
132- return err ;
133-
134- return 0 ;
135- }
136-
137103/*
138104 * Class LED driver.
139105 */
@@ -347,15 +313,47 @@ static int create_netxbig_led(struct platform_device *pdev,
347313 return devm_led_classdev_register (& pdev -> dev , & led_dat -> cdev );
348314}
349315
350- static int gpio_ext_get_of_pdata (struct device * dev , struct device_node * np ,
351- struct netxbig_gpio_ext * gpio_ext )
316+ /**
317+ * netxbig_gpio_ext_remove() - Clean up GPIO extension data
318+ * @data: managed resource data to clean up
319+ *
320+ * Since we pick GPIO descriptors from another device than the device our
321+ * driver is probing to, we need to register a specific callback to free
322+ * these up using managed resources.
323+ */
324+ static void netxbig_gpio_ext_remove (void * data )
325+ {
326+ struct netxbig_gpio_ext * gpio_ext = data ;
327+ int i ;
328+
329+ for (i = 0 ; i < gpio_ext -> num_addr ; i ++ )
330+ gpiod_put (gpio_ext -> addr [i ]);
331+ for (i = 0 ; i < gpio_ext -> num_data ; i ++ )
332+ gpiod_put (gpio_ext -> data [i ]);
333+ gpiod_put (gpio_ext -> enable );
334+ }
335+
336+ /**
337+ * netxbig_gpio_ext_get() - Obtain GPIO extension device data
338+ * @dev: main LED device
339+ * @gpio_ext_dev: the GPIO extension device
340+ * @gpio_ext: the data structure holding the GPIO extension data
341+ *
342+ * This function walks the subdevice that only contain GPIO line
343+ * handles in the device tree and obtains the GPIO descriptors from that
344+ * device.
345+ */
346+ static int netxbig_gpio_ext_get (struct device * dev ,
347+ struct device * gpio_ext_dev ,
348+ struct netxbig_gpio_ext * gpio_ext )
352349{
353- int * addr , * data ;
350+ struct gpio_desc * * addr , * * data ;
354351 int num_addr , num_data ;
352+ struct gpio_desc * gpiod ;
355353 int ret ;
356354 int i ;
357355
358- ret = of_gpio_named_count ( np , "addr-gpios " );
356+ ret = gpiod_count ( gpio_ext_dev , "addr" );
359357 if (ret < 0 ) {
360358 dev_err (dev ,
361359 "Failed to count GPIOs in DT property addr-gpios\n" );
@@ -366,16 +364,25 @@ static int gpio_ext_get_of_pdata(struct device *dev, struct device_node *np,
366364 if (!addr )
367365 return - ENOMEM ;
368366
367+ /*
368+ * We cannot use devm_ managed resources with these GPIO descriptors
369+ * since they are associated with the "GPIO extension device" which
370+ * does not probe any driver. The device tree parser will however
371+ * populate a platform device for it so we can anyway obtain the
372+ * GPIO descriptors from the device.
373+ */
369374 for (i = 0 ; i < num_addr ; i ++ ) {
370- ret = of_get_named_gpio (np , "addr-gpios" , i );
371- if (ret < 0 )
372- return ret ;
373- addr [i ] = ret ;
375+ gpiod = gpiod_get_index (gpio_ext_dev , "addr" , i ,
376+ GPIOD_OUT_LOW );
377+ if (IS_ERR (gpiod ))
378+ return PTR_ERR (gpiod );
379+ gpiod_set_consumer_name (gpiod , "GPIO extension addr" );
380+ addr [i ] = gpiod ;
374381 }
375382 gpio_ext -> addr = addr ;
376383 gpio_ext -> num_addr = num_addr ;
377384
378- ret = of_gpio_named_count ( np , "data-gpios " );
385+ ret = gpiod_count ( gpio_ext_dev , "data" );
379386 if (ret < 0 ) {
380387 dev_err (dev ,
381388 "Failed to count GPIOs in DT property data-gpios\n" );
@@ -387,30 +394,35 @@ static int gpio_ext_get_of_pdata(struct device *dev, struct device_node *np,
387394 return - ENOMEM ;
388395
389396 for (i = 0 ; i < num_data ; i ++ ) {
390- ret = of_get_named_gpio (np , "data-gpios" , i );
391- if (ret < 0 )
392- return ret ;
393- data [i ] = ret ;
397+ gpiod = gpiod_get_index (gpio_ext_dev , "data" , i ,
398+ GPIOD_OUT_LOW );
399+ if (IS_ERR (gpiod ))
400+ return PTR_ERR (gpiod );
401+ gpiod_set_consumer_name (gpiod , "GPIO extension data" );
402+ data [i ] = gpiod ;
394403 }
395404 gpio_ext -> data = data ;
396405 gpio_ext -> num_data = num_data ;
397406
398- ret = of_get_named_gpio ( np , "enable-gpio " , 0 );
399- if (ret < 0 ) {
407+ gpiod = gpiod_get ( gpio_ext_dev , "enable" , GPIOD_OUT_LOW );
408+ if (IS_ERR ( gpiod ) ) {
400409 dev_err (dev ,
401410 "Failed to get GPIO from DT property enable-gpio\n" );
402- return ret ;
411+ return PTR_ERR ( gpiod ) ;
403412 }
404- gpio_ext -> enable = ret ;
413+ gpiod_set_consumer_name (gpiod , "GPIO extension enable" );
414+ gpio_ext -> enable = gpiod ;
405415
406- return 0 ;
416+ return devm_add_action_or_reset ( dev , netxbig_gpio_ext_remove , gpio_ext ) ;
407417}
408418
409419static int netxbig_leds_get_of_pdata (struct device * dev ,
410420 struct netxbig_led_platform_data * pdata )
411421{
412422 struct device_node * np = dev -> of_node ;
413423 struct device_node * gpio_ext_np ;
424+ struct platform_device * gpio_ext_pdev ;
425+ struct device * gpio_ext_dev ;
414426 struct device_node * child ;
415427 struct netxbig_gpio_ext * gpio_ext ;
416428 struct netxbig_led_timer * timers ;
@@ -426,13 +438,19 @@ static int netxbig_leds_get_of_pdata(struct device *dev,
426438 dev_err (dev , "Failed to get DT handle gpio-ext\n" );
427439 return - EINVAL ;
428440 }
441+ gpio_ext_pdev = of_find_device_by_node (gpio_ext_np );
442+ if (!gpio_ext_pdev ) {
443+ dev_err (dev , "Failed to find platform device for gpio-ext\n" );
444+ return - ENODEV ;
445+ }
446+ gpio_ext_dev = & gpio_ext_pdev -> dev ;
429447
430448 gpio_ext = devm_kzalloc (dev , sizeof (* gpio_ext ), GFP_KERNEL );
431449 if (!gpio_ext ) {
432450 of_node_put (gpio_ext_np );
433451 return - ENOMEM ;
434452 }
435- ret = gpio_ext_get_of_pdata (dev , gpio_ext_np , gpio_ext );
453+ ret = netxbig_gpio_ext_get (dev , gpio_ext_dev , gpio_ext );
436454 of_node_put (gpio_ext_np );
437455 if (ret )
438456 return ret ;
@@ -585,10 +603,6 @@ static int netxbig_led_probe(struct platform_device *pdev)
585603 if (!leds_data )
586604 return - ENOMEM ;
587605
588- ret = gpio_ext_init (pdev , pdata -> gpio_ext );
589- if (ret < 0 )
590- return ret ;
591-
592606 for (i = 0 ; i < pdata -> num_leds ; i ++ ) {
593607 ret = create_netxbig_led (pdev , pdata ,
594608 & leds_data [i ], & pdata -> leds [i ]);
0 commit comments