void __iomem *ts_base;
dma_addr_t bus_addr;
struct task_struct *thread;
+ bool enable;
+ struct mutex sysfs_mutex;
uint16_t max_x;
uint16_t max_y;
return 0;
}
+static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct ft5406 *ts = (struct ft5406 *)dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", ts->enable);
+}
+
+static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ft5406 *ts = (struct ft5406 *)dev_get_drvdata(dev);
+ unsigned int val;
+ int error;
+
+ error = kstrtouint(buf, 0, &val);
+ if (error)
+ return error;
+
+ mutex_lock(&ts->sysfs_mutex);
+
+ if (ts->enable == !!val)
+ goto out;
+
+ if (val) {
+ ts->thread = kthread_run(ft5406_thread, ts, "ft5406");
+ if (IS_ERR(ts->thread)) {
+ dev_err(dev, "Failed to create kernel thread");
+ goto out;
+ }
+ } else {
+ error = kthread_stop(ts->thread);
+ if (unlikely(error)) {
+ dev_err(dev, "Failed to stop kernel thread");
+ goto out;
+ }
+ }
+ ts->enable = !!val;
+
+out:
+ mutex_unlock(&ts->sysfs_mutex);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(enable);
+
+static struct attribute *rpi_ft5406_attrs[] = {
+ &dev_attr_enable.attr,
+ NULL
+};
+
+static const struct attribute_group rpi_ft5406_attr_group = {
+ .attrs = rpi_ft5406_attrs,
+};
+
static int ft5406_probe(struct platform_device *pdev)
{
int err = 0;
goto out;
}
+ ts->enable = true;
+ mutex_init(&ts->sysfs_mutex);
+
+ err = sysfs_create_group(&dev->kobj, &rpi_ft5406_attr_group);
+ if (err) {
+ dev_err(dev, "failed to create sysfs group: %d\n", err);
+ goto out;
+ }
+
/* create thread that polls the touch events */
ts->thread = kthread_run(ft5406_thread, ts, "ft5406");
- if (ts->thread == NULL) {
+ if (IS_ERR(ts->thread))
+ {
dev_err(dev, "Failed to create kernel thread");
err = -ENOMEM;
- goto out;
+ goto out_sysfs;
}
return 0;
+out_sysfs:
+ sysfs_remove_group(&dev->kobj, &rpi_ft5406_attr_group);
out:
if (ts->bus_addr) {
dma_free_coherent(dev, PAGE_SIZE, ts->ts_base, ts->bus_addr);
dev_info(dev, "Removing rpi-ft5406\n");
- kthread_stop(ts->thread);
+ sysfs_remove_group(&dev->kobj, &rpi_ft5406_attr_group);
+
+ if (ts->enable)
+ kthread_stop(ts->thread);
if (ts->bus_addr)
dma_free_coherent(dev, PAGE_SIZE, ts->ts_base, ts->bus_addr);