1 /*
2  * Copyright (c) 2017 Red Hat, Inc
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published by
6  * the Free Software Foundation.
7  */
8 
9 #define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
10 
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/libps2.h>
14 #include <linux/i2c.h>
15 #include <linux/serio.h>
16 #include <linux/slab.h>
17 #include <linux/workqueue.h>
18 #include "psmouse.h"
19 
20 struct psmouse_smbus_dev {
21 	struct i2c_board_info board;
22 	struct psmouse *psmouse;
23 	struct i2c_client *client;
24 	struct list_head node;
25 	bool dead;
26 	bool need_deactivate;
27 };
28 
29 static LIST_HEAD(psmouse_smbus_list);
30 static DEFINE_MUTEX(psmouse_smbus_mutex);
31 
32 static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter)
33 {
34 	struct psmouse_smbus_dev *smbdev;
35 
36 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY))
37 		return;
38 
39 	mutex_lock(&psmouse_smbus_mutex);
40 
41 	list_for_each_entry(smbdev, &psmouse_smbus_list, node) {
42 		if (smbdev->dead)
43 			continue;
44 
45 		if (smbdev->client)
46 			continue;
47 
48 		/*
49 		 * Here would be a good place to check if device is actually
50 		 * present, but it seems that SMBus will not respond unless we
51 		 * fully reset PS/2 connection.  So cross our fingers, and try
52 		 * to switch over, hopefully our system will not have too many
53 		 * "host notify" I2C adapters.
54 		 */
55 		psmouse_dbg(smbdev->psmouse,
56 			    "SMBus candidate adapter appeared, triggering rescan\n");
57 		serio_rescan(smbdev->psmouse->ps2dev.serio);
58 	}
59 
60 	mutex_unlock(&psmouse_smbus_mutex);
61 }
62 
63 static void psmouse_smbus_detach_i2c_client(struct i2c_client *client)
64 {
65 	struct psmouse_smbus_dev *smbdev, *tmp;
66 
67 	mutex_lock(&psmouse_smbus_mutex);
68 
69 	list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
70 		if (smbdev->client != client)
71 			continue;
72 
73 		kfree(client->dev.platform_data);
74 		client->dev.platform_data = NULL;
75 
76 		if (!smbdev->dead) {
77 			psmouse_dbg(smbdev->psmouse,
78 				    "Marking SMBus companion %s as gone\n",
79 				    dev_name(&smbdev->client->dev));
80 			smbdev->dead = true;
81 			serio_rescan(smbdev->psmouse->ps2dev.serio);
82 		} else {
83 			list_del(&smbdev->node);
84 			kfree(smbdev);
85 		}
86 	}
87 
88 	mutex_unlock(&psmouse_smbus_mutex);
89 }
90 
91 static int psmouse_smbus_notifier_call(struct notifier_block *nb,
92 				       unsigned long action, void *data)
93 {
94 	struct device *dev = data;
95 
96 	switch (action) {
97 	case BUS_NOTIFY_ADD_DEVICE:
98 		if (dev->type == &i2c_adapter_type)
99 			psmouse_smbus_check_adapter(to_i2c_adapter(dev));
100 		break;
101 
102 	case BUS_NOTIFY_REMOVED_DEVICE:
103 		if (dev->type == &i2c_client_type)
104 			psmouse_smbus_detach_i2c_client(to_i2c_client(dev));
105 		break;
106 	}
107 
108 	return 0;
109 }
110 
111 static struct notifier_block psmouse_smbus_notifier = {
112 	.notifier_call = psmouse_smbus_notifier_call,
113 };
114 
115 static psmouse_ret_t psmouse_smbus_process_byte(struct psmouse *psmouse)
116 {
117 	return PSMOUSE_FULL_PACKET;
118 }
119 
120 static int psmouse_smbus_reconnect(struct psmouse *psmouse)
121 {
122 	struct psmouse_smbus_dev *smbdev = psmouse->private;
123 
124 	if (smbdev->need_deactivate)
125 		psmouse_deactivate(psmouse);
126 
127 	return 0;
128 }
129 
130 struct psmouse_smbus_removal_work {
131 	struct work_struct work;
132 	struct i2c_client *client;
133 };
134 
135 static void psmouse_smbus_remove_i2c_device(struct work_struct *work)
136 {
137 	struct psmouse_smbus_removal_work *rwork =
138 		container_of(work, struct psmouse_smbus_removal_work, work);
139 
140 	dev_dbg(&rwork->client->dev, "destroying SMBus companion device\n");
141 	i2c_unregister_device(rwork->client);
142 
143 	kfree(rwork);
144 }
145 
146 /*
147  * This schedules removal of SMBus companion device. We have to do
148  * it in a separate tread to avoid deadlocking on psmouse_mutex in
149  * case the device has a trackstick (which is also driven by psmouse).
150  *
151  * Note that this may be racing with i2c adapter removal, but we
152  * can't do anything about that: i2c automatically destroys clients
153  * attached to an adapter that is being removed. This has to be
154  * fixed in i2c core.
155  */
156 static void psmouse_smbus_schedule_remove(struct i2c_client *client)
157 {
158 	struct psmouse_smbus_removal_work *rwork;
159 
160 	rwork = kzalloc(sizeof(*rwork), GFP_KERNEL);
161 	if (rwork) {
162 		INIT_WORK(&rwork->work, psmouse_smbus_remove_i2c_device);
163 		rwork->client = client;
164 
165 		schedule_work(&rwork->work);
166 	}
167 }
168 
169 static void psmouse_smbus_disconnect(struct psmouse *psmouse)
170 {
171 	struct psmouse_smbus_dev *smbdev = psmouse->private;
172 
173 	mutex_lock(&psmouse_smbus_mutex);
174 
175 	if (smbdev->dead) {
176 		list_del(&smbdev->node);
177 		kfree(smbdev);
178 	} else {
179 		smbdev->dead = true;
180 		psmouse_dbg(smbdev->psmouse,
181 			    "posting removal request for SMBus companion %s\n",
182 			    dev_name(&smbdev->client->dev));
183 		psmouse_smbus_schedule_remove(smbdev->client);
184 	}
185 
186 	mutex_unlock(&psmouse_smbus_mutex);
187 
188 	psmouse->private = NULL;
189 }
190 
191 static int psmouse_smbus_create_companion(struct device *dev, void *data)
192 {
193 	struct psmouse_smbus_dev *smbdev = data;
194 	unsigned short addr_list[] = { smbdev->board.addr, I2C_CLIENT_END };
195 	struct i2c_adapter *adapter;
196 
197 	adapter = i2c_verify_adapter(dev);
198 	if (!adapter)
199 		return 0;
200 
201 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY))
202 		return 0;
203 
204 	smbdev->client = i2c_new_probed_device(adapter, &smbdev->board,
205 					       addr_list, NULL);
206 	if (!smbdev->client)
207 		return 0;
208 
209 	/* We have our(?) device, stop iterating i2c bus. */
210 	return 1;
211 }
212 
213 void psmouse_smbus_cleanup(struct psmouse *psmouse)
214 {
215 	struct psmouse_smbus_dev *smbdev, *tmp;
216 
217 	mutex_lock(&psmouse_smbus_mutex);
218 
219 	list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
220 		if (psmouse == smbdev->psmouse) {
221 			list_del(&smbdev->node);
222 			kfree(smbdev);
223 		}
224 	}
225 
226 	mutex_unlock(&psmouse_smbus_mutex);
227 }
228 
229 int psmouse_smbus_init(struct psmouse *psmouse,
230 		       const struct i2c_board_info *board,
231 		       const void *pdata, size_t pdata_size,
232 		       bool need_deactivate,
233 		       bool leave_breadcrumbs)
234 {
235 	struct psmouse_smbus_dev *smbdev;
236 	int error;
237 
238 	smbdev = kzalloc(sizeof(*smbdev), GFP_KERNEL);
239 	if (!smbdev)
240 		return -ENOMEM;
241 
242 	smbdev->psmouse = psmouse;
243 	smbdev->board = *board;
244 	smbdev->need_deactivate = need_deactivate;
245 
246 	if (pdata) {
247 		smbdev->board.platform_data = kmemdup(pdata, pdata_size,
248 						      GFP_KERNEL);
249 		if (!smbdev->board.platform_data) {
250 			kfree(smbdev);
251 			return -ENOMEM;
252 		}
253 	}
254 
255 	if (need_deactivate)
256 		psmouse_deactivate(psmouse);
257 
258 	psmouse->private = smbdev;
259 	psmouse->protocol_handler = psmouse_smbus_process_byte;
260 	psmouse->reconnect = psmouse_smbus_reconnect;
261 	psmouse->fast_reconnect = psmouse_smbus_reconnect;
262 	psmouse->disconnect = psmouse_smbus_disconnect;
263 	psmouse->resync_time = 0;
264 
265 	mutex_lock(&psmouse_smbus_mutex);
266 	list_add_tail(&smbdev->node, &psmouse_smbus_list);
267 	mutex_unlock(&psmouse_smbus_mutex);
268 
269 	/* Bind to already existing adapters right away */
270 	error = i2c_for_each_dev(smbdev, psmouse_smbus_create_companion);
271 
272 	if (smbdev->client) {
273 		/* We have our companion device */
274 		return 0;
275 	}
276 
277 	/*
278 	 * If we did not create i2c device we will not need platform
279 	 * data even if we are leaving breadcrumbs.
280 	 */
281 	kfree(smbdev->board.platform_data);
282 	smbdev->board.platform_data = NULL;
283 
284 	if (error < 0 || !leave_breadcrumbs) {
285 		mutex_lock(&psmouse_smbus_mutex);
286 		list_del(&smbdev->node);
287 		mutex_unlock(&psmouse_smbus_mutex);
288 
289 		kfree(smbdev);
290 	}
291 
292 	return error < 0 ? error : -EAGAIN;
293 }
294 
295 int __init psmouse_smbus_module_init(void)
296 {
297 	int error;
298 
299 	error = bus_register_notifier(&i2c_bus_type, &psmouse_smbus_notifier);
300 	if (error) {
301 		pr_err("failed to register i2c bus notifier: %d\n", error);
302 		return error;
303 	}
304 
305 	return 0;
306 }
307 
308 void psmouse_smbus_module_exit(void)
309 {
310 	bus_unregister_notifier(&i2c_bus_type, &psmouse_smbus_notifier);
311 	flush_scheduled_work();
312 }
313