24
24
#include <linux/pinctrl/consumer.h>
25
25
#include <linux/poll.h>
26
26
#include <linux/rbtree.h>
27
- #include <linux/rwsem.h>
28
27
#include <linux/seq_file.h>
29
28
#include <linux/spinlock.h>
30
29
#include <linux/timekeeping.h>
@@ -205,9 +204,9 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
205
204
unsigned int i ;
206
205
int ret ;
207
206
208
- guard (rwsem_read )(& lh -> gdev -> sem );
207
+ guard (srcu )(& lh -> gdev -> srcu );
209
208
210
- if (!lh -> gdev -> chip )
209
+ if (!rcu_dereference ( lh -> gdev -> chip ) )
211
210
return - ENODEV ;
212
211
213
212
switch (cmd ) {
@@ -1520,9 +1519,9 @@ static long linereq_ioctl(struct file *file, unsigned int cmd,
1520
1519
struct linereq * lr = file -> private_data ;
1521
1520
void __user * ip = (void __user * )arg ;
1522
1521
1523
- guard (rwsem_read )(& lr -> gdev -> sem );
1522
+ guard (srcu )(& lr -> gdev -> srcu );
1524
1523
1525
- if (!lr -> gdev -> chip )
1524
+ if (!rcu_dereference ( lr -> gdev -> chip ) )
1526
1525
return - ENODEV ;
1527
1526
1528
1527
switch (cmd ) {
@@ -1551,9 +1550,9 @@ static __poll_t linereq_poll(struct file *file,
1551
1550
struct linereq * lr = file -> private_data ;
1552
1551
__poll_t events = 0 ;
1553
1552
1554
- guard (rwsem_read )(& lr -> gdev -> sem );
1553
+ guard (srcu )(& lr -> gdev -> srcu );
1555
1554
1556
- if (!lr -> gdev -> chip )
1555
+ if (!rcu_dereference ( lr -> gdev -> chip ) )
1557
1556
return EPOLLHUP | EPOLLERR ;
1558
1557
1559
1558
poll_wait (file , & lr -> wait , wait );
@@ -1573,9 +1572,9 @@ static ssize_t linereq_read(struct file *file, char __user *buf,
1573
1572
ssize_t bytes_read = 0 ;
1574
1573
int ret ;
1575
1574
1576
- guard (rwsem_read )(& lr -> gdev -> sem );
1575
+ guard (srcu )(& lr -> gdev -> srcu );
1577
1576
1578
- if (!lr -> gdev -> chip )
1577
+ if (!rcu_dereference ( lr -> gdev -> chip ) )
1579
1578
return - ENODEV ;
1580
1579
1581
1580
if (count < sizeof (le ))
@@ -1874,9 +1873,9 @@ static __poll_t lineevent_poll(struct file *file,
1874
1873
struct lineevent_state * le = file -> private_data ;
1875
1874
__poll_t events = 0 ;
1876
1875
1877
- guard (rwsem_read )(& le -> gdev -> sem );
1876
+ guard (srcu )(& le -> gdev -> srcu );
1878
1877
1879
- if (!le -> gdev -> chip )
1878
+ if (!rcu_dereference ( le -> gdev -> chip ) )
1880
1879
return EPOLLHUP | EPOLLERR ;
1881
1880
1882
1881
poll_wait (file , & le -> wait , wait );
@@ -1912,9 +1911,9 @@ static ssize_t lineevent_read(struct file *file, char __user *buf,
1912
1911
ssize_t ge_size ;
1913
1912
int ret ;
1914
1913
1915
- guard (rwsem_read )(& le -> gdev -> sem );
1914
+ guard (srcu )(& le -> gdev -> srcu );
1916
1915
1917
- if (!le -> gdev -> chip )
1916
+ if (!rcu_dereference ( le -> gdev -> chip ) )
1918
1917
return - ENODEV ;
1919
1918
1920
1919
/*
@@ -1995,9 +1994,9 @@ static long lineevent_ioctl(struct file *file, unsigned int cmd,
1995
1994
void __user * ip = (void __user * )arg ;
1996
1995
struct gpiohandle_data ghd ;
1997
1996
1998
- guard (rwsem_read )(& le -> gdev -> sem );
1997
+ guard (srcu )(& le -> gdev -> srcu );
1999
1998
2000
- if (!le -> gdev -> chip )
1999
+ if (!rcu_dereference ( le -> gdev -> chip ) )
2001
2000
return - ENODEV ;
2002
2001
2003
2002
/*
@@ -2295,10 +2294,13 @@ static void gpio_v2_line_info_changed_to_v1(
2295
2294
static void gpio_desc_to_lineinfo (struct gpio_desc * desc ,
2296
2295
struct gpio_v2_line_info * info )
2297
2296
{
2298
- struct gpio_chip * gc = desc -> gdev -> chip ;
2299
2297
unsigned long dflags ;
2300
2298
const char * label ;
2301
2299
2300
+ CLASS (gpio_chip_guard , guard )(desc );
2301
+ if (!guard .gc )
2302
+ return ;
2303
+
2302
2304
memset (info , 0 , sizeof (* info ));
2303
2305
info -> offset = gpio_chip_hwgpio (desc );
2304
2306
@@ -2331,8 +2333,8 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
2331
2333
test_bit (FLAG_USED_AS_IRQ , & dflags ) ||
2332
2334
test_bit (FLAG_EXPORT , & dflags ) ||
2333
2335
test_bit (FLAG_SYSFS , & dflags ) ||
2334
- !gpiochip_line_is_valid (gc , info -> offset ) ||
2335
- !pinctrl_gpio_can_use_line (gc , info -> offset ))
2336
+ !gpiochip_line_is_valid (guard . gc , info -> offset ) ||
2337
+ !pinctrl_gpio_can_use_line (guard . gc , info -> offset ))
2336
2338
info -> flags |= GPIO_V2_LINE_FLAG_USED ;
2337
2339
2338
2340
if (test_bit (FLAG_IS_OUT , & dflags ))
@@ -2505,10 +2507,10 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2505
2507
struct gpio_device * gdev = cdev -> gdev ;
2506
2508
void __user * ip = (void __user * )arg ;
2507
2509
2508
- guard (rwsem_read )(& gdev -> sem );
2510
+ guard (srcu )(& gdev -> srcu );
2509
2511
2510
2512
/* We fail any subsequent ioctl():s when the chip is gone */
2511
- if (!gdev -> chip )
2513
+ if (!rcu_dereference ( gdev -> chip ) )
2512
2514
return - ENODEV ;
2513
2515
2514
2516
/* Fill in the struct and pass to userspace */
@@ -2591,9 +2593,9 @@ static __poll_t lineinfo_watch_poll(struct file *file,
2591
2593
struct gpio_chardev_data * cdev = file -> private_data ;
2592
2594
__poll_t events = 0 ;
2593
2595
2594
- guard (rwsem_read )(& cdev -> gdev -> sem );
2596
+ guard (srcu )(& cdev -> gdev -> srcu );
2595
2597
2596
- if (!cdev -> gdev -> chip )
2598
+ if (!rcu_dereference ( cdev -> gdev -> chip ) )
2597
2599
return EPOLLHUP | EPOLLERR ;
2598
2600
2599
2601
poll_wait (file , & cdev -> wait , pollt );
@@ -2614,9 +2616,9 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
2614
2616
int ret ;
2615
2617
size_t event_size ;
2616
2618
2617
- guard (rwsem_read )(& cdev -> gdev -> sem );
2619
+ guard (srcu )(& cdev -> gdev -> srcu );
2618
2620
2619
- if (!cdev -> gdev -> chip )
2621
+ if (!rcu_dereference ( cdev -> gdev -> chip ) )
2620
2622
return - ENODEV ;
2621
2623
2622
2624
#ifndef CONFIG_GPIO_CDEV_V1
@@ -2691,10 +2693,10 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
2691
2693
struct gpio_chardev_data * cdev ;
2692
2694
int ret = - ENOMEM ;
2693
2695
2694
- guard (rwsem_read )(& gdev -> sem );
2696
+ guard (srcu )(& gdev -> srcu );
2695
2697
2696
2698
/* Fail on open if the backing gpiochip is gone */
2697
- if (!gdev -> chip )
2699
+ if (!rcu_dereference ( gdev -> chip ) )
2698
2700
return - ENODEV ;
2699
2701
2700
2702
cdev = kzalloc (sizeof (* cdev ), GFP_KERNEL );
@@ -2781,6 +2783,7 @@ static const struct file_operations gpio_fileops = {
2781
2783
2782
2784
int gpiolib_cdev_register (struct gpio_device * gdev , dev_t devt )
2783
2785
{
2786
+ struct gpio_chip * gc ;
2784
2787
int ret ;
2785
2788
2786
2789
cdev_init (& gdev -> chrdev , & gpio_fileops );
@@ -2791,8 +2794,13 @@ int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt)
2791
2794
if (ret )
2792
2795
return ret ;
2793
2796
2794
- chip_dbg (gdev -> chip , "added GPIO chardev (%d:%d)\n" ,
2795
- MAJOR (devt ), gdev -> id );
2797
+ guard (srcu )(& gdev -> srcu );
2798
+
2799
+ gc = rcu_dereference (gdev -> chip );
2800
+ if (!gc )
2801
+ return - ENODEV ;
2802
+
2803
+ chip_dbg (gc , "added GPIO chardev (%d:%d)\n" , MAJOR (devt ), gdev -> id );
2796
2804
2797
2805
return 0 ;
2798
2806
}
0 commit comments