#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/rwsem.h>
+#include <linux/mutex.h>
#include <linux/usb/input.h>
#include <linux/map_to_7segment.h>
u8 lcdMap[ARRAY_SIZE(lcdMap)]; /* state of LCD, LED ... */
int key_code; /* last reported key */
+ struct mutex sysfs_mutex;
+
unsigned int shutdown:1;
int stat_ix;
* sysfs interface
******************************************************************************/
-static DECLARE_RWSEM(sysfs_rwsema);
-
/* Interface to the 7-segments translation table aka. char set.
*/
static ssize_t show_map(struct device *dev, struct device_attribute *attr,
*/
static ssize_t show_line(struct device *dev, char *buf, int a, int b)
{
- struct yealink_dev *yld;
+ struct yealink_dev *yld = dev_get_drvdata(dev);
int i;
- down_read(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_read(&sysfs_rwsema);
- return -ENODEV;
- }
+ guard(mutex)(&yld->sysfs_mutex);
for (i = a; i < b; i++)
*buf++ = lcdMap[i].type;
*buf++ = '\n';
*buf = 0;
- up_read(&sysfs_rwsema);
return 3 + ((b - a) << 1);
}
static ssize_t store_line(struct device *dev, const char *buf, size_t count,
int el, size_t len)
{
- struct yealink_dev *yld;
+ struct yealink_dev *yld = dev_get_drvdata(dev);
int i;
- down_write(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_write(&sysfs_rwsema);
- return -ENODEV;
- }
+ guard(mutex)(&yld->sysfs_mutex);
if (len > count)
len = count;
for (i = 0; i < len; i++)
setChar(yld, el++, buf[i]);
- up_write(&sysfs_rwsema);
return count;
}
static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct yealink_dev *yld;
+ struct yealink_dev *yld = dev_get_drvdata(dev);
int i, ret = 1;
- down_read(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_read(&sysfs_rwsema);
- return -ENODEV;
- }
+ guard(mutex)(&yld->sysfs_mutex);
for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
if (lcdMap[i].type != '.')
yld->lcdMap[i] == ' ' ? " " : "on",
lcdMap[i].u.p.name);
}
- up_read(&sysfs_rwsema);
+
return ret;
}
static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
int chr)
{
- struct yealink_dev *yld;
+ struct yealink_dev *yld = dev_get_drvdata(dev);
int i;
- down_write(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_write(&sysfs_rwsema);
- return -ENODEV;
- }
+ guard(mutex)(&yld->sysfs_mutex);
for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
if (lcdMap[i].type != '.')
}
}
- up_write(&sysfs_rwsema);
return count;
}
*/
/* Stores raw ringtone data in the phone */
-static ssize_t store_ringtone(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t store_ringtone(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct yealink_dev *yld;
+ struct yealink_dev *yld = dev_get_drvdata(dev);
- down_write(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_write(&sysfs_rwsema);
- return -ENODEV;
- }
+ guard(mutex)(&yld->sysfs_mutex);
/* TODO locking with async usb control interface??? */
yealink_set_ringtone(yld, (char *)buf, count);
- up_write(&sysfs_rwsema);
+
return count;
}
static void usb_disconnect(struct usb_interface *intf)
{
- struct yealink_dev *yld;
-
- down_write(&sysfs_rwsema);
- yld = usb_get_intfdata(intf);
- usb_set_intfdata(intf, NULL);
- up_write(&sysfs_rwsema);
+ struct yealink_dev *yld = usb_get_intfdata(intf);
usb_cleanup(yld, 0);
+ usb_set_intfdata(intf, NULL);
}
static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
yld->udev = udev;
yld->intf = intf;
+ mutex_init(&yld->sysfs_mutex);
yld->idev = input_dev = input_allocate_device();
if (!input_dev)