Input: psmouse - tweak PSMOUSE_DEFINE_ATTR to support raw set callbacks
We want to support attr->set callbacks that may need psmouse->state to not be updated, or may want to manually deal w/ enabling and disabling the device. To do that, we create __PSMOUSE_DEFINE_ATTR which enables us to set a 'protect' argument specifying whether or not the set callback should be protected with psmouse_disable and state setting. Signed-off-by: Andres Salomon <dilinger@debian.org> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
committed by
Dmitry Torokhov
parent
8bf020ee96
commit
68d482214b
@@ -1401,25 +1401,29 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
|
|||||||
|
|
||||||
psmouse = serio_get_drvdata(serio);
|
psmouse = serio_get_drvdata(serio);
|
||||||
|
|
||||||
if (psmouse->state == PSMOUSE_IGNORE) {
|
if (attr->protect) {
|
||||||
retval = -ENODEV;
|
if (psmouse->state == PSMOUSE_IGNORE) {
|
||||||
goto out_unlock;
|
retval = -ENODEV;
|
||||||
}
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
|
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
|
||||||
parent = serio_get_drvdata(serio->parent);
|
parent = serio_get_drvdata(serio->parent);
|
||||||
psmouse_deactivate(parent);
|
psmouse_deactivate(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
psmouse_deactivate(psmouse);
|
psmouse_deactivate(psmouse);
|
||||||
|
}
|
||||||
|
|
||||||
retval = attr->set(psmouse, attr->data, buf, count);
|
retval = attr->set(psmouse, attr->data, buf, count);
|
||||||
|
|
||||||
if (retval != -ENODEV)
|
if (attr->protect) {
|
||||||
psmouse_activate(psmouse);
|
if (retval != -ENODEV)
|
||||||
|
psmouse_activate(psmouse);
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
psmouse_activate(parent);
|
psmouse_activate(parent);
|
||||||
|
}
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&psmouse_mutex);
|
mutex_unlock(&psmouse_mutex);
|
||||||
|
@@ -106,6 +106,7 @@ struct psmouse_attribute {
|
|||||||
ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
|
ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
|
||||||
ssize_t (*set)(struct psmouse *psmouse, void *data,
|
ssize_t (*set)(struct psmouse *psmouse, void *data,
|
||||||
const char *buf, size_t count);
|
const char *buf, size_t count);
|
||||||
|
int protect;
|
||||||
};
|
};
|
||||||
#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr)
|
#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr)
|
||||||
|
|
||||||
@@ -114,7 +115,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at
|
|||||||
ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
|
ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
|
||||||
const char *buf, size_t count);
|
const char *buf, size_t count);
|
||||||
|
|
||||||
#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
|
#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \
|
||||||
static ssize_t _show(struct psmouse *, void *data, char *); \
|
static ssize_t _show(struct psmouse *, void *data, char *); \
|
||||||
static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \
|
static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \
|
||||||
static struct psmouse_attribute psmouse_attr_##_name = { \
|
static struct psmouse_attribute psmouse_attr_##_name = { \
|
||||||
@@ -129,6 +130,10 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
|
|||||||
.data = _data, \
|
.data = _data, \
|
||||||
.show = _show, \
|
.show = _show, \
|
||||||
.set = _set, \
|
.set = _set, \
|
||||||
|
.protect = _protect, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
|
||||||
|
__PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1)
|
||||||
|
|
||||||
#endif /* _PSMOUSE_H */
|
#endif /* _PSMOUSE_H */
|
||||||
|
Reference in New Issue
Block a user