12
12
#include <linux/slab.h>
13
13
#include <linux/spinlock.h>
14
14
#include <linux/platform_device.h>
15
- #include <linux/gpio.h>
16
- #include <linux/of_gpio.h>
15
+ #include <linux/gpio/consumer.h>
17
16
#include <linux/leds.h>
17
+ #include <linux/of.h>
18
+ #include <linux/of_platform.h>
18
19
19
20
struct netxbig_gpio_ext {
20
- unsigned int * addr ;
21
+ struct gpio_desc * * addr ;
21
22
int num_addr ;
22
- unsigned int * data ;
23
+ struct gpio_desc * * data ;
23
24
int num_data ;
24
- unsigned int enable ;
25
+ struct gpio_desc * enable ;
25
26
};
26
27
27
28
enum netxbig_led_mode {
@@ -69,22 +70,22 @@ static void gpio_ext_set_addr(struct netxbig_gpio_ext *gpio_ext, int addr)
69
70
int pin ;
70
71
71
72
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 );
73
74
}
74
75
75
76
static void gpio_ext_set_data (struct netxbig_gpio_ext * gpio_ext , int data )
76
77
{
77
78
int pin ;
78
79
79
80
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 );
81
82
}
82
83
83
84
static void gpio_ext_enable_select (struct netxbig_gpio_ext * gpio_ext )
84
85
{
85
86
/* 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 );
88
89
}
89
90
90
91
static 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,
99
100
spin_unlock_irqrestore (& gpio_ext_lock , flags );
100
101
}
101
102
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
-
137
103
/*
138
104
* Class LED driver.
139
105
*/
@@ -347,15 +313,47 @@ static int create_netxbig_led(struct platform_device *pdev,
347
313
return devm_led_classdev_register (& pdev -> dev , & led_dat -> cdev );
348
314
}
349
315
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 )
352
349
{
353
- int * addr , * data ;
350
+ struct gpio_desc * * addr , * * data ;
354
351
int num_addr , num_data ;
352
+ struct gpio_desc * gpiod ;
355
353
int ret ;
356
354
int i ;
357
355
358
- ret = of_gpio_named_count ( np , "addr-gpios " );
356
+ ret = gpiod_count ( gpio_ext_dev , "addr" );
359
357
if (ret < 0 ) {
360
358
dev_err (dev ,
361
359
"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,
366
364
if (!addr )
367
365
return - ENOMEM ;
368
366
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
+ */
369
374
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 ;
374
381
}
375
382
gpio_ext -> addr = addr ;
376
383
gpio_ext -> num_addr = num_addr ;
377
384
378
- ret = of_gpio_named_count ( np , "data-gpios " );
385
+ ret = gpiod_count ( gpio_ext_dev , "data" );
379
386
if (ret < 0 ) {
380
387
dev_err (dev ,
381
388
"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,
387
394
return - ENOMEM ;
388
395
389
396
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 ;
394
403
}
395
404
gpio_ext -> data = data ;
396
405
gpio_ext -> num_data = num_data ;
397
406
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 ) ) {
400
409
dev_err (dev ,
401
410
"Failed to get GPIO from DT property enable-gpio\n" );
402
- return ret ;
411
+ return PTR_ERR ( gpiod ) ;
403
412
}
404
- gpio_ext -> enable = ret ;
413
+ gpiod_set_consumer_name (gpiod , "GPIO extension enable" );
414
+ gpio_ext -> enable = gpiod ;
405
415
406
- return 0 ;
416
+ return devm_add_action_or_reset ( dev , netxbig_gpio_ext_remove , gpio_ext ) ;
407
417
}
408
418
409
419
static int netxbig_leds_get_of_pdata (struct device * dev ,
410
420
struct netxbig_led_platform_data * pdata )
411
421
{
412
422
struct device_node * np = dev -> of_node ;
413
423
struct device_node * gpio_ext_np ;
424
+ struct platform_device * gpio_ext_pdev ;
425
+ struct device * gpio_ext_dev ;
414
426
struct device_node * child ;
415
427
struct netxbig_gpio_ext * gpio_ext ;
416
428
struct netxbig_led_timer * timers ;
@@ -426,13 +438,19 @@ static int netxbig_leds_get_of_pdata(struct device *dev,
426
438
dev_err (dev , "Failed to get DT handle gpio-ext\n" );
427
439
return - EINVAL ;
428
440
}
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 ;
429
447
430
448
gpio_ext = devm_kzalloc (dev , sizeof (* gpio_ext ), GFP_KERNEL );
431
449
if (!gpio_ext ) {
432
450
of_node_put (gpio_ext_np );
433
451
return - ENOMEM ;
434
452
}
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 );
436
454
of_node_put (gpio_ext_np );
437
455
if (ret )
438
456
return ret ;
@@ -585,10 +603,6 @@ static int netxbig_led_probe(struct platform_device *pdev)
585
603
if (!leds_data )
586
604
return - ENOMEM ;
587
605
588
- ret = gpio_ext_init (pdev , pdata -> gpio_ext );
589
- if (ret < 0 )
590
- return ret ;
591
-
592
606
for (i = 0 ; i < pdata -> num_leds ; i ++ ) {
593
607
ret = create_netxbig_led (pdev , pdata ,
594
608
& leds_data [i ], & pdata -> leds [i ]);
0 commit comments