2 * Copyright (c) 2017 Red Hat, Inc
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.
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
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
;
29 static LIST_HEAD(psmouse_smbus_list
);
30 static DEFINE_MUTEX(psmouse_smbus_mutex
);
32 static void psmouse_smbus_check_adapter(struct i2c_adapter
*adapter
)
34 struct psmouse_smbus_dev
*smbdev
;
36 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_HOST_NOTIFY
))
39 mutex_lock(&psmouse_smbus_mutex
);
41 list_for_each_entry(smbdev
, &psmouse_smbus_list
, node
) {
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.
55 psmouse_dbg(smbdev
->psmouse
,
56 "SMBus candidate adapter appeared, triggering rescan\n");
57 serio_rescan(smbdev
->psmouse
->ps2dev
.serio
);
60 mutex_unlock(&psmouse_smbus_mutex
);
63 static void psmouse_smbus_detach_i2c_client(struct i2c_client
*client
)
65 struct psmouse_smbus_dev
*smbdev
, *tmp
;
67 mutex_lock(&psmouse_smbus_mutex
);
69 list_for_each_entry_safe(smbdev
, tmp
, &psmouse_smbus_list
, node
) {
70 if (smbdev
->client
!= client
)
73 kfree(client
->dev
.platform_data
);
74 client
->dev
.platform_data
= NULL
;
77 psmouse_dbg(smbdev
->psmouse
,
78 "Marking SMBus companion %s as gone\n",
79 dev_name(&smbdev
->client
->dev
));
81 serio_rescan(smbdev
->psmouse
->ps2dev
.serio
);
83 list_del(&smbdev
->node
);
88 mutex_unlock(&psmouse_smbus_mutex
);
91 static int psmouse_smbus_notifier_call(struct notifier_block
*nb
,
92 unsigned long action
, void *data
)
94 struct device
*dev
= data
;
97 case BUS_NOTIFY_ADD_DEVICE
:
98 if (dev
->type
== &i2c_adapter_type
)
99 psmouse_smbus_check_adapter(to_i2c_adapter(dev
));
102 case BUS_NOTIFY_REMOVED_DEVICE
:
103 if (dev
->type
== &i2c_client_type
)
104 psmouse_smbus_detach_i2c_client(to_i2c_client(dev
));
111 static struct notifier_block psmouse_smbus_notifier
= {
112 .notifier_call
= psmouse_smbus_notifier_call
,
115 static psmouse_ret_t
psmouse_smbus_process_byte(struct psmouse
*psmouse
)
117 return PSMOUSE_FULL_PACKET
;
120 static int psmouse_smbus_reconnect(struct psmouse
*psmouse
)
122 struct psmouse_smbus_dev
*smbdev
= psmouse
->private;
124 if (smbdev
->need_deactivate
)
125 psmouse_deactivate(psmouse
);
130 struct psmouse_smbus_removal_work
{
131 struct work_struct work
;
132 struct i2c_client
*client
;
135 static void psmouse_smbus_remove_i2c_device(struct work_struct
*work
)
137 struct psmouse_smbus_removal_work
*rwork
=
138 container_of(work
, struct psmouse_smbus_removal_work
, work
);
140 dev_dbg(&rwork
->client
->dev
, "destroying SMBus companion device\n");
141 i2c_unregister_device(rwork
->client
);
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).
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
156 static void psmouse_smbus_schedule_remove(struct i2c_client
*client
)
158 struct psmouse_smbus_removal_work
*rwork
;
160 rwork
= kzalloc(sizeof(*rwork
), GFP_KERNEL
);
162 INIT_WORK(&rwork
->work
, psmouse_smbus_remove_i2c_device
);
163 rwork
->client
= client
;
165 schedule_work(&rwork
->work
);
169 static void psmouse_smbus_disconnect(struct psmouse
*psmouse
)
171 struct psmouse_smbus_dev
*smbdev
= psmouse
->private;
173 mutex_lock(&psmouse_smbus_mutex
);
176 list_del(&smbdev
->node
);
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
);
186 mutex_unlock(&psmouse_smbus_mutex
);
188 psmouse
->private = NULL
;
191 static int psmouse_smbus_create_companion(struct device
*dev
, void *data
)
193 struct psmouse_smbus_dev
*smbdev
= data
;
194 unsigned short addr_list
[] = { smbdev
->board
.addr
, I2C_CLIENT_END
};
195 struct i2c_adapter
*adapter
;
197 adapter
= i2c_verify_adapter(dev
);
201 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_HOST_NOTIFY
))
204 smbdev
->client
= i2c_new_probed_device(adapter
, &smbdev
->board
,
209 /* We have our(?) device, stop iterating i2c bus. */
213 void psmouse_smbus_cleanup(struct psmouse
*psmouse
)
215 struct psmouse_smbus_dev
*smbdev
, *tmp
;
217 mutex_lock(&psmouse_smbus_mutex
);
219 list_for_each_entry_safe(smbdev
, tmp
, &psmouse_smbus_list
, node
) {
220 if (psmouse
== smbdev
->psmouse
) {
221 list_del(&smbdev
->node
);
226 mutex_unlock(&psmouse_smbus_mutex
);
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
)
235 struct psmouse_smbus_dev
*smbdev
;
238 smbdev
= kzalloc(sizeof(*smbdev
), GFP_KERNEL
);
242 smbdev
->psmouse
= psmouse
;
243 smbdev
->board
= *board
;
244 smbdev
->need_deactivate
= need_deactivate
;
247 smbdev
->board
.platform_data
= kmemdup(pdata
, pdata_size
,
249 if (!smbdev
->board
.platform_data
) {
256 psmouse_deactivate(psmouse
);
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;
265 mutex_lock(&psmouse_smbus_mutex
);
266 list_add_tail(&smbdev
->node
, &psmouse_smbus_list
);
267 mutex_unlock(&psmouse_smbus_mutex
);
269 /* Bind to already existing adapters right away */
270 error
= i2c_for_each_dev(smbdev
, psmouse_smbus_create_companion
);
272 if (smbdev
->client
) {
273 /* We have our companion device */
278 * If we did not create i2c device we will not need platform
279 * data even if we are leaving breadcrumbs.
281 kfree(smbdev
->board
.platform_data
);
282 smbdev
->board
.platform_data
= NULL
;
284 if (error
< 0 || !leave_breadcrumbs
) {
285 mutex_lock(&psmouse_smbus_mutex
);
286 list_del(&smbdev
->node
);
287 mutex_unlock(&psmouse_smbus_mutex
);
292 return error
< 0 ? error
: -EAGAIN
;
295 int __init
psmouse_smbus_module_init(void)
299 error
= bus_register_notifier(&i2c_bus_type
, &psmouse_smbus_notifier
);
301 pr_err("failed to register i2c bus notifier: %d\n", error
);
308 void psmouse_smbus_module_exit(void)
310 bus_unregister_notifier(&i2c_bus_type
, &psmouse_smbus_notifier
);
311 flush_scheduled_work();