3636#include <linux/kernel.h>
3737#include <linux/slab.h>
3838#include <linux/module.h>
39- #include <linux/rwsem .h>
39+ #include <linux/mutex .h>
4040#include <linux/usb/input.h>
4141#include <linux/map_to_7segment.h>
4242
@@ -103,6 +103,8 @@ struct yealink_dev {
103103 u8 lcdMap [ARRAY_SIZE (lcdMap )]; /* state of LCD, LED ... */
104104 int key_code ; /* last reported key */
105105
106+ struct mutex sysfs_mutex ;
107+
106108 unsigned int shutdown :1 ;
107109
108110 int stat_ix ;
@@ -548,8 +550,6 @@ static void input_close(struct input_dev *dev)
548550 * sysfs interface
549551 ******************************************************************************/
550552
551- static DECLARE_RWSEM (sysfs_rwsema );
552-
553553/* Interface to the 7-segments translation table aka. char set.
554554 */
555555static ssize_t show_map (struct device * dev , struct device_attribute * attr ,
@@ -580,15 +580,10 @@ static ssize_t store_map(struct device *dev, struct device_attribute *attr,
580580 */
581581static ssize_t show_line (struct device * dev , char * buf , int a , int b )
582582{
583- struct yealink_dev * yld ;
583+ struct yealink_dev * yld = dev_get_drvdata ( dev ) ;
584584 int i ;
585585
586- down_read (& sysfs_rwsema );
587- yld = dev_get_drvdata (dev );
588- if (yld == NULL ) {
589- up_read (& sysfs_rwsema );
590- return - ENODEV ;
591- }
586+ guard (mutex )(& yld -> sysfs_mutex );
592587
593588 for (i = a ; i < b ; i ++ )
594589 * buf ++ = lcdMap [i ].type ;
@@ -598,7 +593,6 @@ static ssize_t show_line(struct device *dev, char *buf, int a, int b)
598593 * buf ++ = '\n' ;
599594 * buf = 0 ;
600595
601- up_read (& sysfs_rwsema );
602596 return 3 + ((b - a ) << 1 );
603597}
604598
@@ -630,22 +624,16 @@ static ssize_t show_line3(struct device *dev, struct device_attribute *attr,
630624static ssize_t store_line (struct device * dev , const char * buf , size_t count ,
631625 int el , size_t len )
632626{
633- struct yealink_dev * yld ;
627+ struct yealink_dev * yld = dev_get_drvdata ( dev ) ;
634628 int i ;
635629
636- down_write (& sysfs_rwsema );
637- yld = dev_get_drvdata (dev );
638- if (yld == NULL ) {
639- up_write (& sysfs_rwsema );
640- return - ENODEV ;
641- }
630+ guard (mutex )(& yld -> sysfs_mutex );
642631
643632 if (len > count )
644633 len = count ;
645634 for (i = 0 ; i < len ; i ++ )
646635 setChar (yld , el ++ , buf [i ]);
647636
648- up_write (& sysfs_rwsema );
649637 return count ;
650638}
651639
@@ -675,15 +663,10 @@ static ssize_t store_line3(struct device *dev, struct device_attribute *attr,
675663static ssize_t get_icons (struct device * dev , struct device_attribute * attr ,
676664 char * buf )
677665{
678- struct yealink_dev * yld ;
666+ struct yealink_dev * yld = dev_get_drvdata ( dev ) ;
679667 int i , ret = 1 ;
680668
681- down_read (& sysfs_rwsema );
682- yld = dev_get_drvdata (dev );
683- if (yld == NULL ) {
684- up_read (& sysfs_rwsema );
685- return - ENODEV ;
686- }
669+ guard (mutex )(& yld -> sysfs_mutex );
687670
688671 for (i = 0 ; i < ARRAY_SIZE (lcdMap ); i ++ ) {
689672 if (lcdMap [i ].type != '.' )
@@ -692,23 +675,18 @@ static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
692675 yld -> lcdMap [i ] == ' ' ? " " : "on" ,
693676 lcdMap [i ].u .p .name );
694677 }
695- up_read ( & sysfs_rwsema );
678+
696679 return ret ;
697680}
698681
699682/* Change the visibility of a particular element. */
700683static ssize_t set_icon (struct device * dev , const char * buf , size_t count ,
701684 int chr )
702685{
703- struct yealink_dev * yld ;
686+ struct yealink_dev * yld = dev_get_drvdata ( dev ) ;
704687 int i ;
705688
706- down_write (& sysfs_rwsema );
707- yld = dev_get_drvdata (dev );
708- if (yld == NULL ) {
709- up_write (& sysfs_rwsema );
710- return - ENODEV ;
711- }
689+ guard (mutex )(& yld -> sysfs_mutex );
712690
713691 for (i = 0 ; i < ARRAY_SIZE (lcdMap ); i ++ ) {
714692 if (lcdMap [i ].type != '.' )
@@ -719,7 +697,6 @@ static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
719697 }
720698 }
721699
722- up_write (& sysfs_rwsema );
723700 return count ;
724701}
725702
@@ -739,22 +716,16 @@ static ssize_t hide_icon(struct device *dev, struct device_attribute *attr,
739716 */
740717
741718/* Stores raw ringtone data in the phone */
742- static ssize_t store_ringtone (struct device * dev ,
743- struct device_attribute * attr ,
744- const char * buf , size_t count )
719+ static ssize_t store_ringtone (struct device * dev , struct device_attribute * attr ,
720+ const char * buf , size_t count )
745721{
746- struct yealink_dev * yld ;
722+ struct yealink_dev * yld = dev_get_drvdata ( dev ) ;
747723
748- down_write (& sysfs_rwsema );
749- yld = dev_get_drvdata (dev );
750- if (yld == NULL ) {
751- up_write (& sysfs_rwsema );
752- return - ENODEV ;
753- }
724+ guard (mutex )(& yld -> sysfs_mutex );
754725
755726 /* TODO locking with async usb control interface??? */
756727 yealink_set_ringtone (yld , (char * )buf , count );
757- up_write ( & sysfs_rwsema );
728+
758729 return count ;
759730}
760731
@@ -835,14 +806,10 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
835806
836807static void usb_disconnect (struct usb_interface * intf )
837808{
838- struct yealink_dev * yld ;
839-
840- down_write (& sysfs_rwsema );
841- yld = usb_get_intfdata (intf );
842- usb_set_intfdata (intf , NULL );
843- up_write (& sysfs_rwsema );
809+ struct yealink_dev * yld = usb_get_intfdata (intf );
844810
845811 usb_cleanup (yld , 0 );
812+ usb_set_intfdata (intf , NULL );
846813}
847814
848815static int usb_probe (struct usb_interface * intf , const struct usb_device_id * id )
@@ -870,6 +837,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
870837
871838 yld -> udev = udev ;
872839 yld -> intf = intf ;
840+ mutex_init (& yld -> sysfs_mutex );
873841
874842 yld -> idev = input_dev = input_allocate_device ();
875843 if (!input_dev )
0 commit comments