Skip to content

Commit 83e6b40

Browse files
bentissJiri Kosina
authored andcommitted
HID: wacom: EKR: have the wacom resources dynamically allocated
If we want to have one input device per remote, it's better to have our own struct wacom_remote which is dynamically allocated. Signed-off-by: Benjamin Tissoires <[email protected]> Acked-by: Ping Cheng <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent e6f2813 commit 83e6b40

File tree

4 files changed

+94
-66
lines changed

4 files changed

+94
-66
lines changed

drivers/hid/wacom.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ struct wacom_group_leds {
116116
u8 select; /* status led selector (0..3) */
117117
};
118118

119+
struct wacom_remote {
120+
spinlock_t remote_lock;
121+
struct kfifo remote_fifo;
122+
struct kobject *remote_dir;
123+
struct attribute_group remote_group[WACOM_MAX_REMOTES];
124+
__u32 serial[WACOM_MAX_REMOTES];
125+
};
126+
119127
struct wacom {
120128
struct usb_device *usbdev;
121129
struct usb_interface *intf;
@@ -125,8 +133,7 @@ struct wacom {
125133
struct work_struct wireless_work;
126134
struct work_struct battery_work;
127135
struct work_struct remote_work;
128-
spinlock_t remote_lock;
129-
struct kfifo remote_fifo;
136+
struct wacom_remote *remote;
130137
struct wacom_leds {
131138
struct wacom_group_leds *groups;
132139
u8 llv; /* status led brightness no button (1..127) */
@@ -137,8 +144,6 @@ struct wacom {
137144
struct power_supply *ac;
138145
struct power_supply_desc battery_desc;
139146
struct power_supply_desc ac_desc;
140-
struct kobject *remote_dir;
141-
struct attribute_group remote_group[5];
142147
bool resources;
143148
};
144149

drivers/hid/wacom_sys.c

Lines changed: 77 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,18 +1298,18 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial,
12981298
int index)
12991299
{
13001300
int error = 0;
1301-
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1301+
struct wacom_remote *remote = wacom->remote;
13021302

1303-
wacom_wac->serial[index] = serial;
1303+
remote->serial[index] = serial;
13041304

1305-
wacom->remote_group[index].name = devm_kasprintf(&wacom->hdev->dev,
1306-
GFP_KERNEL,
1307-
"%d", serial);
1308-
if (!wacom->remote_group[index].name)
1305+
remote->remote_group[index].name = devm_kasprintf(&wacom->hdev->dev,
1306+
GFP_KERNEL,
1307+
"%d", serial);
1308+
if (!remote->remote_group[index].name)
13091309
return -ENOMEM;
13101310

1311-
error = sysfs_create_group(wacom->remote_dir,
1312-
&wacom->remote_group[index]);
1311+
error = sysfs_create_group(remote->remote_dir,
1312+
&remote->remote_group[index]);
13131313
if (error) {
13141314
hid_err(wacom->hdev,
13151315
"cannot create sysfs group err: %d\n", error);
@@ -1321,22 +1321,22 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial,
13211321

13221322
static void wacom_remote_destroy_attr_group(struct wacom *wacom, __u32 serial)
13231323
{
1324-
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1324+
struct wacom_remote *remote = wacom->remote;
13251325
int i;
13261326

13271327
if (!serial)
13281328
return;
13291329

13301330
for (i = 0; i < WACOM_MAX_REMOTES; i++) {
1331-
if (wacom_wac->serial[i] == serial) {
1332-
wacom_wac->serial[i] = 0;
1331+
if (remote->serial[i] == serial) {
1332+
remote->serial[i] = 0;
13331333
wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN;
1334-
if (wacom->remote_group[i].name) {
1335-
sysfs_remove_group(wacom->remote_dir,
1336-
&wacom->remote_group[i]);
1334+
if (remote->remote_group[i].name) {
1335+
sysfs_remove_group(remote->remote_dir,
1336+
&remote->remote_group[i]);
13371337
devm_kfree(&wacom->hdev->dev,
1338-
(char *)wacom->remote_group[i].name);
1339-
wacom->remote_group[i].name = NULL;
1338+
(char *)remote->remote_group[i].name);
1339+
remote->remote_group[i].name = NULL;
13401340
}
13411341
}
13421342
}
@@ -1398,27 +1398,57 @@ static const struct attribute *remote_unpair_attrs[] = {
13981398
NULL
13991399
};
14001400

1401-
static int wacom_initialize_remote(struct wacom *wacom)
1401+
static void wacom_remotes_destroy(void *data)
1402+
{
1403+
struct wacom *wacom = data;
1404+
struct wacom_remote *remote = wacom->remote;
1405+
1406+
if (!remote)
1407+
return;
1408+
1409+
kobject_put(remote->remote_dir);
1410+
kfifo_free(&remote->remote_fifo);
1411+
wacom->remote = NULL;
1412+
}
1413+
1414+
static int wacom_initialize_remotes(struct wacom *wacom)
14021415
{
14031416
int error = 0;
1404-
struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
1417+
struct wacom_remote *remote;
14051418
int i;
14061419

14071420
if (wacom->wacom_wac.features.type != REMOTE)
14081421
return 0;
14091422

1410-
wacom->remote_group[0] = remote0_serial_group;
1411-
wacom->remote_group[1] = remote1_serial_group;
1412-
wacom->remote_group[2] = remote2_serial_group;
1413-
wacom->remote_group[3] = remote3_serial_group;
1414-
wacom->remote_group[4] = remote4_serial_group;
1423+
remote = devm_kzalloc(&wacom->hdev->dev, sizeof(*wacom->remote),
1424+
GFP_KERNEL);
1425+
if (!remote)
1426+
return -ENOMEM;
14151427

1416-
wacom->remote_dir = kobject_create_and_add("wacom_remote",
1417-
&wacom->hdev->dev.kobj);
1418-
if (!wacom->remote_dir)
1428+
wacom->remote = remote;
1429+
1430+
spin_lock_init(&remote->remote_lock);
1431+
1432+
error = kfifo_alloc(&remote->remote_fifo,
1433+
5 * sizeof(struct wacom_remote_data),
1434+
GFP_KERNEL);
1435+
if (error) {
1436+
hid_err(wacom->hdev, "failed allocating remote_fifo\n");
14191437
return -ENOMEM;
1438+
}
14201439

1421-
error = sysfs_create_files(wacom->remote_dir, remote_unpair_attrs);
1440+
remote->remote_group[0] = remote0_serial_group;
1441+
remote->remote_group[1] = remote1_serial_group;
1442+
remote->remote_group[2] = remote2_serial_group;
1443+
remote->remote_group[3] = remote3_serial_group;
1444+
remote->remote_group[4] = remote4_serial_group;
1445+
1446+
remote->remote_dir = kobject_create_and_add("wacom_remote",
1447+
&wacom->hdev->dev.kobj);
1448+
if (!remote->remote_dir)
1449+
return -ENOMEM;
1450+
1451+
error = sysfs_create_files(remote->remote_dir, remote_unpair_attrs);
14221452

14231453
if (error) {
14241454
hid_err(wacom->hdev,
@@ -1428,9 +1458,14 @@ static int wacom_initialize_remote(struct wacom *wacom)
14281458

14291459
for (i = 0; i < WACOM_MAX_REMOTES; i++) {
14301460
wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN;
1431-
wacom_wac->serial[i] = 0;
1461+
remote->serial[i] = 0;
14321462
}
14331463

1464+
error = devm_add_action_or_reset(&wacom->hdev->dev,
1465+
wacom_remotes_destroy, wacom);
1466+
if (error)
1467+
return error;
1468+
14341469
return 0;
14351470
}
14361471

@@ -1740,7 +1775,7 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
17401775
if (error)
17411776
goto fail_leds;
17421777

1743-
error = wacom_initialize_remote(wacom);
1778+
error = wacom_initialize_remotes(wacom);
17441779
if (error)
17451780
goto fail_remote;
17461781
}
@@ -1792,7 +1827,6 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
17921827
fail_quirks:
17931828
hid_hw_stop(hdev);
17941829
fail_hw_start:
1795-
kobject_put(wacom->remote_dir);
17961830
fail_remote:
17971831
fail_leds:
17981832
fail_register_inputs:
@@ -1893,58 +1927,58 @@ static void wacom_wireless_work(struct work_struct *work)
18931927
static void wacom_remote_work(struct work_struct *work)
18941928
{
18951929
struct wacom *wacom = container_of(work, struct wacom, remote_work);
1896-
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1930+
struct wacom_remote *remote = wacom->remote;
18971931
struct wacom_remote_data data;
18981932
unsigned long flags;
18991933
unsigned int count;
19001934
u32 serial;
19011935
int i, k;
19021936

1903-
spin_lock_irqsave(&wacom->remote_lock, flags);
1937+
spin_lock_irqsave(&remote->remote_lock, flags);
19041938

1905-
count = kfifo_out(&wacom->remote_fifo, &data, sizeof(data));
1939+
count = kfifo_out(&remote->remote_fifo, &data, sizeof(data));
19061940

19071941
if (count != sizeof(data)) {
19081942
hid_err(wacom->hdev,
19091943
"workitem triggered without status available\n");
1910-
spin_unlock_irqrestore(&wacom->remote_lock, flags);
1944+
spin_unlock_irqrestore(&remote->remote_lock, flags);
19111945
return;
19121946
}
19131947

1914-
if (!kfifo_is_empty(&wacom->remote_fifo))
1948+
if (!kfifo_is_empty(&remote->remote_fifo))
19151949
wacom_schedule_work(&wacom->wacom_wac, WACOM_WORKER_REMOTE);
19161950

1917-
spin_unlock_irqrestore(&wacom->remote_lock, flags);
1951+
spin_unlock_irqrestore(&remote->remote_lock, flags);
19181952

19191953
for (i = 0; i < WACOM_MAX_REMOTES; i++) {
19201954
serial = data.remote[i].serial;
19211955
if (data.remote[i].connected) {
19221956

1923-
if (wacom_wac->serial[i] == serial)
1957+
if (remote->serial[i] == serial)
19241958
continue;
19251959

1926-
if (wacom_wac->serial[i]) {
1960+
if (remote->serial[i]) {
19271961
wacom_remote_destroy_attr_group(wacom,
1928-
wacom_wac->serial[i]);
1962+
remote->serial[i]);
19291963
}
19301964

19311965
/* A remote can pair more than once with an EKR,
19321966
* check to make sure this serial isn't already paired.
19331967
*/
19341968
for (k = 0; k < WACOM_MAX_REMOTES; k++) {
1935-
if (wacom_wac->serial[k] == serial)
1969+
if (remote->serial[k] == serial)
19361970
break;
19371971
}
19381972

19391973
if (k < WACOM_MAX_REMOTES) {
1940-
wacom_wac->serial[i] = serial;
1974+
remote->serial[i] = serial;
19411975
continue;
19421976
}
19431977
wacom_remote_create_attr_group(wacom, serial, i);
19441978

1945-
} else if (wacom_wac->serial[i]) {
1979+
} else if (remote->serial[i]) {
19461980
wacom_remote_destroy_attr_group(wacom,
1947-
wacom_wac->serial[i]);
1981+
remote->serial[i]);
19481982
}
19491983
}
19501984
}
@@ -1992,16 +2026,6 @@ static int wacom_probe(struct hid_device *hdev,
19922026
INIT_WORK(&wacom->wireless_work, wacom_wireless_work);
19932027
INIT_WORK(&wacom->battery_work, wacom_battery_work);
19942028
INIT_WORK(&wacom->remote_work, wacom_remote_work);
1995-
spin_lock_init(&wacom->remote_lock);
1996-
1997-
if (kfifo_alloc(&wacom->remote_fifo,
1998-
5 * sizeof(struct wacom_remote_data),
1999-
GFP_KERNEL)) {
2000-
dev_err(&hdev->dev,
2001-
"%s:failed allocating remote_fifo\n", __func__);
2002-
error = -ENOMEM;
2003-
goto fail_type;
2004-
}
20052029

20062030
/* ask for the report descriptor to be loaded by HID */
20072031
error = hid_parse(hdev);
@@ -2025,7 +2049,6 @@ static int wacom_probe(struct hid_device *hdev,
20252049
return 0;
20262050

20272051
fail_parse:
2028-
kfifo_free(&wacom->remote_fifo);
20292052
fail_type:
20302053
hid_set_drvdata(hdev, NULL);
20312054
return error;
@@ -2045,8 +2068,6 @@ static void wacom_remove(struct hid_device *hdev)
20452068
cancel_work_sync(&wacom->wireless_work);
20462069
cancel_work_sync(&wacom->battery_work);
20472070
cancel_work_sync(&wacom->remote_work);
2048-
kfifo_free(&wacom->remote_fifo);
2049-
kobject_put(wacom->remote_dir);
20502071
if (hdev->bus == BUS_BLUETOOTH)
20512072
device_remove_file(&hdev->dev, &dev_attr_speed);
20522073

drivers/hid/wacom_wac.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
753753
unsigned char *data = wacom_wac->data;
754754
struct input_dev *input = wacom_wac->pad_input;
755755
struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
756+
struct wacom_remote *remote = wacom->remote;
756757
struct wacom_features *features = &wacom_wac->features;
757758
int bat_charging, bat_percent, touch_ring_mode;
758759
__u32 serial;
@@ -807,7 +808,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
807808
touch_ring_mode = (data[11] & 0xC0) >> 6;
808809

809810
for (i = 0; i < WACOM_MAX_REMOTES; i++) {
810-
if (wacom_wac->serial[i] == serial)
811+
if (remote->serial[i] == serial)
811812
wacom->led.groups[i].select = touch_ring_mode;
812813
}
813814

@@ -827,6 +828,7 @@ static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len)
827828
{
828829
struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
829830
unsigned char *data = wacom_wac->data;
831+
struct wacom_remote *remote = wacom->remote;
830832
struct wacom_remote_data remote_data;
831833
unsigned long flags;
832834
int i, ret;
@@ -845,16 +847,16 @@ static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len)
845847
remote_data.remote[i].connected = connected;
846848
}
847849

848-
spin_lock_irqsave(&wacom->remote_lock, flags);
850+
spin_lock_irqsave(&remote->remote_lock, flags);
849851

850-
ret = kfifo_in(&wacom->remote_fifo, &remote_data, sizeof(remote_data));
852+
ret = kfifo_in(&remote->remote_fifo, &remote_data, sizeof(remote_data));
851853
if (ret != sizeof(remote_data)) {
852-
spin_unlock_irqrestore(&wacom->remote_lock, flags);
854+
spin_unlock_irqrestore(&remote->remote_lock, flags);
853855
hid_err(wacom->hdev, "Can't queue Remote status event.\n");
854856
return;
855857
}
856858

857-
spin_unlock_irqrestore(&wacom->remote_lock, flags);
859+
spin_unlock_irqrestore(&remote->remote_lock, flags);
858860

859861
wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE);
860862
}

drivers/hid/wacom_wac.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ struct wacom_wac {
234234
unsigned char data[WACOM_PKGLEN_MAX];
235235
int tool[2];
236236
int id[2];
237-
__u32 serial[5];
237+
__u32 serial[2];
238238
bool reporting_data;
239239
struct wacom_features features;
240240
struct wacom_shared *shared;

0 commit comments

Comments
 (0)