|
@@ -81,6 +81,7 @@ struct appledisplay {
|
|
|
struct delayed_work work;
|
|
|
int button_pressed;
|
|
|
spinlock_t lock;
|
|
|
+ struct mutex sysfslock; /* concurrent read and write */
|
|
|
};
|
|
|
|
|
|
static atomic_t count_displays = ATOMIC_INIT(0);
|
|
@@ -144,6 +145,7 @@ static int appledisplay_bl_update_status(struct backlight_device *bd)
|
|
|
struct appledisplay *pdata = bl_get_data(bd);
|
|
|
int retval;
|
|
|
|
|
|
+ mutex_lock(&pdata->sysfslock);
|
|
|
pdata->msgdata[0] = 0x10;
|
|
|
pdata->msgdata[1] = bd->props.brightness;
|
|
|
|
|
@@ -156,15 +158,17 @@ static int appledisplay_bl_update_status(struct backlight_device *bd)
|
|
|
0,
|
|
|
pdata->msgdata, 2,
|
|
|
ACD_USB_TIMEOUT);
|
|
|
-
|
|
|
+ mutex_unlock(&pdata->sysfslock);
|
|
|
+
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
static int appledisplay_bl_get_brightness(struct backlight_device *bd)
|
|
|
{
|
|
|
struct appledisplay *pdata = bl_get_data(bd);
|
|
|
- int retval;
|
|
|
+ int retval, brightness;
|
|
|
|
|
|
+ mutex_lock(&pdata->sysfslock);
|
|
|
retval = usb_control_msg(
|
|
|
pdata->udev,
|
|
|
usb_rcvctrlpipe(pdata->udev, 0),
|
|
@@ -174,11 +178,13 @@ static int appledisplay_bl_get_brightness(struct backlight_device *bd)
|
|
|
0,
|
|
|
pdata->msgdata, 2,
|
|
|
ACD_USB_TIMEOUT);
|
|
|
+ brightness = pdata->msgdata[1];
|
|
|
+ mutex_unlock(&pdata->sysfslock);
|
|
|
|
|
|
if (retval < 0)
|
|
|
return retval;
|
|
|
else
|
|
|
- return pdata->msgdata[1];
|
|
|
+ return brightness;
|
|
|
}
|
|
|
|
|
|
static const struct backlight_ops appledisplay_bl_data = {
|
|
@@ -241,6 +247,7 @@ static int appledisplay_probe(struct usb_interface *iface,
|
|
|
|
|
|
spin_lock_init(&pdata->lock);
|
|
|
INIT_DELAYED_WORK(&pdata->work, appledisplay_work);
|
|
|
+ mutex_init(&pdata->sysfslock);
|
|
|
|
|
|
/* Allocate buffer for control messages */
|
|
|
pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL);
|