surface_dtx.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Surface Book (gen. 2 and later) detachment system (DTX) driver.
  4. *
  5. * Provides a user-space interface to properly handle clipboard/tablet
  6. * (containing screen and processor) detachment from the base of the device
  7. * (containing the keyboard and optionally a discrete GPU). Allows to
  8. * acknowledge (to speed things up), abort (e.g. in case the dGPU is still in
  9. * use), or request detachment via user-space.
  10. *
  11. * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com>
  12. */
  13. #include <linux/fs.h>
  14. #include <linux/input.h>
  15. #include <linux/ioctl.h>
  16. #include <linux/kernel.h>
  17. #include <linux/kfifo.h>
  18. #include <linux/kref.h>
  19. #include <linux/miscdevice.h>
  20. #include <linux/module.h>
  21. #include <linux/mutex.h>
  22. #include <linux/platform_device.h>
  23. #include <linux/poll.h>
  24. #include <linux/rwsem.h>
  25. #include <linux/slab.h>
  26. #include <linux/workqueue.h>
  27. #include <linux/surface_aggregator/controller.h>
  28. #include <linux/surface_aggregator/device.h>
  29. #include <linux/surface_aggregator/dtx.h>
  30. /* -- SSAM interface. ------------------------------------------------------- */
  31. enum sam_event_cid_bas {
  32. SAM_EVENT_CID_DTX_CONNECTION = 0x0c,
  33. SAM_EVENT_CID_DTX_REQUEST = 0x0e,
  34. SAM_EVENT_CID_DTX_CANCEL = 0x0f,
  35. SAM_EVENT_CID_DTX_LATCH_STATUS = 0x11,
  36. };
  37. enum ssam_bas_base_state {
  38. SSAM_BAS_BASE_STATE_DETACH_SUCCESS = 0x00,
  39. SSAM_BAS_BASE_STATE_ATTACHED = 0x01,
  40. SSAM_BAS_BASE_STATE_NOT_FEASIBLE = 0x02,
  41. };
  42. enum ssam_bas_latch_status {
  43. SSAM_BAS_LATCH_STATUS_CLOSED = 0x00,
  44. SSAM_BAS_LATCH_STATUS_OPENED = 0x01,
  45. SSAM_BAS_LATCH_STATUS_FAILED_TO_OPEN = 0x02,
  46. SSAM_BAS_LATCH_STATUS_FAILED_TO_REMAIN_OPEN = 0x03,
  47. SSAM_BAS_LATCH_STATUS_FAILED_TO_CLOSE = 0x04,
  48. };
  49. enum ssam_bas_cancel_reason {
  50. SSAM_BAS_CANCEL_REASON_NOT_FEASIBLE = 0x00, /* Low battery. */
  51. SSAM_BAS_CANCEL_REASON_TIMEOUT = 0x02,
  52. SSAM_BAS_CANCEL_REASON_FAILED_TO_OPEN = 0x03,
  53. SSAM_BAS_CANCEL_REASON_FAILED_TO_REMAIN_OPEN = 0x04,
  54. SSAM_BAS_CANCEL_REASON_FAILED_TO_CLOSE = 0x05,
  55. };
  56. struct ssam_bas_base_info {
  57. u8 state;
  58. u8 base_id;
  59. } __packed;
  60. static_assert(sizeof(struct ssam_bas_base_info) == 2);
  61. SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_lock, {
  62. .target_category = SSAM_SSH_TC_BAS,
  63. .target_id = SSAM_SSH_TID_SAM,
  64. .command_id = 0x06,
  65. .instance_id = 0x00,
  66. });
  67. SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_unlock, {
  68. .target_category = SSAM_SSH_TC_BAS,
  69. .target_id = SSAM_SSH_TID_SAM,
  70. .command_id = 0x07,
  71. .instance_id = 0x00,
  72. });
  73. SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_request, {
  74. .target_category = SSAM_SSH_TC_BAS,
  75. .target_id = SSAM_SSH_TID_SAM,
  76. .command_id = 0x08,
  77. .instance_id = 0x00,
  78. });
  79. SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_confirm, {
  80. .target_category = SSAM_SSH_TC_BAS,
  81. .target_id = SSAM_SSH_TID_SAM,
  82. .command_id = 0x09,
  83. .instance_id = 0x00,
  84. });
  85. SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_heartbeat, {
  86. .target_category = SSAM_SSH_TC_BAS,
  87. .target_id = SSAM_SSH_TID_SAM,
  88. .command_id = 0x0a,
  89. .instance_id = 0x00,
  90. });
  91. SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_cancel, {
  92. .target_category = SSAM_SSH_TC_BAS,
  93. .target_id = SSAM_SSH_TID_SAM,
  94. .command_id = 0x0b,
  95. .instance_id = 0x00,
  96. });
  97. SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_base, struct ssam_bas_base_info, {
  98. .target_category = SSAM_SSH_TC_BAS,
  99. .target_id = SSAM_SSH_TID_SAM,
  100. .command_id = 0x0c,
  101. .instance_id = 0x00,
  102. });
  103. SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_device_mode, u8, {
  104. .target_category = SSAM_SSH_TC_BAS,
  105. .target_id = SSAM_SSH_TID_SAM,
  106. .command_id = 0x0d,
  107. .instance_id = 0x00,
  108. });
  109. SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_latch_status, u8, {
  110. .target_category = SSAM_SSH_TC_BAS,
  111. .target_id = SSAM_SSH_TID_SAM,
  112. .command_id = 0x11,
  113. .instance_id = 0x00,
  114. });
  115. /* -- Main structures. ------------------------------------------------------ */
  116. enum sdtx_device_state {
  117. SDTX_DEVICE_SHUTDOWN_BIT = BIT(0),
  118. SDTX_DEVICE_DIRTY_BASE_BIT = BIT(1),
  119. SDTX_DEVICE_DIRTY_MODE_BIT = BIT(2),
  120. SDTX_DEVICE_DIRTY_LATCH_BIT = BIT(3),
  121. };
  122. struct sdtx_device {
  123. struct kref kref;
  124. struct rw_semaphore lock; /* Guards device and controller reference. */
  125. struct device *dev;
  126. struct ssam_controller *ctrl;
  127. unsigned long flags;
  128. struct miscdevice mdev;
  129. wait_queue_head_t waitq;
  130. struct mutex write_lock; /* Guards order of events/notifications. */
  131. struct rw_semaphore client_lock; /* Guards client list. */
  132. struct list_head client_list;
  133. struct delayed_work state_work;
  134. struct {
  135. struct ssam_bas_base_info base;
  136. u8 device_mode;
  137. u8 latch_status;
  138. } state;
  139. struct delayed_work mode_work;
  140. struct input_dev *mode_switch;
  141. struct ssam_event_notifier notif;
  142. };
  143. enum sdtx_client_state {
  144. SDTX_CLIENT_EVENTS_ENABLED_BIT = BIT(0),
  145. };
  146. struct sdtx_client {
  147. struct sdtx_device *ddev;
  148. struct list_head node;
  149. unsigned long flags;
  150. struct fasync_struct *fasync;
  151. struct mutex read_lock; /* Guards FIFO buffer read access. */
  152. DECLARE_KFIFO(buffer, u8, 512);
  153. };
  154. static void __sdtx_device_release(struct kref *kref)
  155. {
  156. struct sdtx_device *ddev = container_of(kref, struct sdtx_device, kref);
  157. mutex_destroy(&ddev->write_lock);
  158. kfree(ddev);
  159. }
  160. static struct sdtx_device *sdtx_device_get(struct sdtx_device *ddev)
  161. {
  162. if (ddev)
  163. kref_get(&ddev->kref);
  164. return ddev;
  165. }
  166. static void sdtx_device_put(struct sdtx_device *ddev)
  167. {
  168. if (ddev)
  169. kref_put(&ddev->kref, __sdtx_device_release);
  170. }
  171. /* -- Firmware value translations. ------------------------------------------ */
  172. static u16 sdtx_translate_base_state(struct sdtx_device *ddev, u8 state)
  173. {
  174. switch (state) {
  175. case SSAM_BAS_BASE_STATE_ATTACHED:
  176. return SDTX_BASE_ATTACHED;
  177. case SSAM_BAS_BASE_STATE_DETACH_SUCCESS:
  178. return SDTX_BASE_DETACHED;
  179. case SSAM_BAS_BASE_STATE_NOT_FEASIBLE:
  180. return SDTX_DETACH_NOT_FEASIBLE;
  181. default:
  182. dev_err(ddev->dev, "unknown base state: %#04x\n", state);
  183. return SDTX_UNKNOWN(state);
  184. }
  185. }
  186. static u16 sdtx_translate_latch_status(struct sdtx_device *ddev, u8 status)
  187. {
  188. switch (status) {
  189. case SSAM_BAS_LATCH_STATUS_CLOSED:
  190. return SDTX_LATCH_CLOSED;
  191. case SSAM_BAS_LATCH_STATUS_OPENED:
  192. return SDTX_LATCH_OPENED;
  193. case SSAM_BAS_LATCH_STATUS_FAILED_TO_OPEN:
  194. return SDTX_ERR_FAILED_TO_OPEN;
  195. case SSAM_BAS_LATCH_STATUS_FAILED_TO_REMAIN_OPEN:
  196. return SDTX_ERR_FAILED_TO_REMAIN_OPEN;
  197. case SSAM_BAS_LATCH_STATUS_FAILED_TO_CLOSE:
  198. return SDTX_ERR_FAILED_TO_CLOSE;
  199. default:
  200. dev_err(ddev->dev, "unknown latch status: %#04x\n", status);
  201. return SDTX_UNKNOWN(status);
  202. }
  203. }
  204. static u16 sdtx_translate_cancel_reason(struct sdtx_device *ddev, u8 reason)
  205. {
  206. switch (reason) {
  207. case SSAM_BAS_CANCEL_REASON_NOT_FEASIBLE:
  208. return SDTX_DETACH_NOT_FEASIBLE;
  209. case SSAM_BAS_CANCEL_REASON_TIMEOUT:
  210. return SDTX_DETACH_TIMEDOUT;
  211. case SSAM_BAS_CANCEL_REASON_FAILED_TO_OPEN:
  212. return SDTX_ERR_FAILED_TO_OPEN;
  213. case SSAM_BAS_CANCEL_REASON_FAILED_TO_REMAIN_OPEN:
  214. return SDTX_ERR_FAILED_TO_REMAIN_OPEN;
  215. case SSAM_BAS_CANCEL_REASON_FAILED_TO_CLOSE:
  216. return SDTX_ERR_FAILED_TO_CLOSE;
  217. default:
  218. dev_err(ddev->dev, "unknown cancel reason: %#04x\n", reason);
  219. return SDTX_UNKNOWN(reason);
  220. }
  221. }
  222. /* -- IOCTLs. --------------------------------------------------------------- */
  223. static int sdtx_ioctl_get_base_info(struct sdtx_device *ddev,
  224. struct sdtx_base_info __user *buf)
  225. {
  226. struct ssam_bas_base_info raw;
  227. struct sdtx_base_info info;
  228. int status;
  229. lockdep_assert_held_read(&ddev->lock);
  230. status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &raw);
  231. if (status < 0)
  232. return status;
  233. info.state = sdtx_translate_base_state(ddev, raw.state);
  234. info.base_id = SDTX_BASE_TYPE_SSH(raw.base_id);
  235. if (copy_to_user(buf, &info, sizeof(info)))
  236. return -EFAULT;
  237. return 0;
  238. }
  239. static int sdtx_ioctl_get_device_mode(struct sdtx_device *ddev, u16 __user *buf)
  240. {
  241. u8 mode;
  242. int status;
  243. lockdep_assert_held_read(&ddev->lock);
  244. status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
  245. if (status < 0)
  246. return status;
  247. return put_user(mode, buf);
  248. }
  249. static int sdtx_ioctl_get_latch_status(struct sdtx_device *ddev, u16 __user *buf)
  250. {
  251. u8 latch;
  252. int status;
  253. lockdep_assert_held_read(&ddev->lock);
  254. status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &latch);
  255. if (status < 0)
  256. return status;
  257. return put_user(sdtx_translate_latch_status(ddev, latch), buf);
  258. }
  259. static long __surface_dtx_ioctl(struct sdtx_client *client, unsigned int cmd, unsigned long arg)
  260. {
  261. struct sdtx_device *ddev = client->ddev;
  262. lockdep_assert_held_read(&ddev->lock);
  263. switch (cmd) {
  264. case SDTX_IOCTL_EVENTS_ENABLE:
  265. set_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags);
  266. return 0;
  267. case SDTX_IOCTL_EVENTS_DISABLE:
  268. clear_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags);
  269. return 0;
  270. case SDTX_IOCTL_LATCH_LOCK:
  271. return ssam_retry(ssam_bas_latch_lock, ddev->ctrl);
  272. case SDTX_IOCTL_LATCH_UNLOCK:
  273. return ssam_retry(ssam_bas_latch_unlock, ddev->ctrl);
  274. case SDTX_IOCTL_LATCH_REQUEST:
  275. return ssam_retry(ssam_bas_latch_request, ddev->ctrl);
  276. case SDTX_IOCTL_LATCH_CONFIRM:
  277. return ssam_retry(ssam_bas_latch_confirm, ddev->ctrl);
  278. case SDTX_IOCTL_LATCH_HEARTBEAT:
  279. return ssam_retry(ssam_bas_latch_heartbeat, ddev->ctrl);
  280. case SDTX_IOCTL_LATCH_CANCEL:
  281. return ssam_retry(ssam_bas_latch_cancel, ddev->ctrl);
  282. case SDTX_IOCTL_GET_BASE_INFO:
  283. return sdtx_ioctl_get_base_info(ddev, (struct sdtx_base_info __user *)arg);
  284. case SDTX_IOCTL_GET_DEVICE_MODE:
  285. return sdtx_ioctl_get_device_mode(ddev, (u16 __user *)arg);
  286. case SDTX_IOCTL_GET_LATCH_STATUS:
  287. return sdtx_ioctl_get_latch_status(ddev, (u16 __user *)arg);
  288. default:
  289. return -EINVAL;
  290. }
  291. }
  292. static long surface_dtx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  293. {
  294. struct sdtx_client *client = file->private_data;
  295. long status;
  296. if (down_read_killable(&client->ddev->lock))
  297. return -ERESTARTSYS;
  298. if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &client->ddev->flags)) {
  299. up_read(&client->ddev->lock);
  300. return -ENODEV;
  301. }
  302. status = __surface_dtx_ioctl(client, cmd, arg);
  303. up_read(&client->ddev->lock);
  304. return status;
  305. }
  306. /* -- File operations. ------------------------------------------------------ */
  307. static int surface_dtx_open(struct inode *inode, struct file *file)
  308. {
  309. struct sdtx_device *ddev = container_of(file->private_data, struct sdtx_device, mdev);
  310. struct sdtx_client *client;
  311. /* Initialize client. */
  312. client = kzalloc_obj(*client);
  313. if (!client)
  314. return -ENOMEM;
  315. client->ddev = sdtx_device_get(ddev);
  316. INIT_LIST_HEAD(&client->node);
  317. mutex_init(&client->read_lock);
  318. INIT_KFIFO(client->buffer);
  319. file->private_data = client;
  320. /* Attach client. */
  321. down_write(&ddev->client_lock);
  322. /*
  323. * Do not add a new client if the device has been shut down. Note that
  324. * it's enough to hold the client_lock here as, during shutdown, we
  325. * only acquire that lock and remove clients after marking the device
  326. * as shut down.
  327. */
  328. if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
  329. up_write(&ddev->client_lock);
  330. mutex_destroy(&client->read_lock);
  331. sdtx_device_put(client->ddev);
  332. kfree(client);
  333. return -ENODEV;
  334. }
  335. list_add_tail(&client->node, &ddev->client_list);
  336. up_write(&ddev->client_lock);
  337. stream_open(inode, file);
  338. return 0;
  339. }
  340. static int surface_dtx_release(struct inode *inode, struct file *file)
  341. {
  342. struct sdtx_client *client = file->private_data;
  343. /* Detach client. */
  344. down_write(&client->ddev->client_lock);
  345. list_del(&client->node);
  346. up_write(&client->ddev->client_lock);
  347. /* Free client. */
  348. sdtx_device_put(client->ddev);
  349. mutex_destroy(&client->read_lock);
  350. kfree(client);
  351. return 0;
  352. }
  353. static ssize_t surface_dtx_read(struct file *file, char __user *buf, size_t count, loff_t *offs)
  354. {
  355. struct sdtx_client *client = file->private_data;
  356. struct sdtx_device *ddev = client->ddev;
  357. unsigned int copied;
  358. int status = 0;
  359. if (down_read_killable(&ddev->lock))
  360. return -ERESTARTSYS;
  361. /* Make sure we're not shut down. */
  362. if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
  363. up_read(&ddev->lock);
  364. return -ENODEV;
  365. }
  366. do {
  367. /* Check availability, wait if necessary. */
  368. if (kfifo_is_empty(&client->buffer)) {
  369. up_read(&ddev->lock);
  370. if (file->f_flags & O_NONBLOCK)
  371. return -EAGAIN;
  372. status = wait_event_interruptible(ddev->waitq,
  373. !kfifo_is_empty(&client->buffer) ||
  374. test_bit(SDTX_DEVICE_SHUTDOWN_BIT,
  375. &ddev->flags));
  376. if (status < 0)
  377. return status;
  378. if (down_read_killable(&ddev->lock))
  379. return -ERESTARTSYS;
  380. /* Need to check that we're not shut down again. */
  381. if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
  382. up_read(&ddev->lock);
  383. return -ENODEV;
  384. }
  385. }
  386. /* Try to read from FIFO. */
  387. if (mutex_lock_interruptible(&client->read_lock)) {
  388. up_read(&ddev->lock);
  389. return -ERESTARTSYS;
  390. }
  391. status = kfifo_to_user(&client->buffer, buf, count, &copied);
  392. mutex_unlock(&client->read_lock);
  393. if (status < 0) {
  394. up_read(&ddev->lock);
  395. return status;
  396. }
  397. /* We might not have gotten anything, check this here. */
  398. if (copied == 0 && (file->f_flags & O_NONBLOCK)) {
  399. up_read(&ddev->lock);
  400. return -EAGAIN;
  401. }
  402. } while (copied == 0);
  403. up_read(&ddev->lock);
  404. return copied;
  405. }
  406. static __poll_t surface_dtx_poll(struct file *file, struct poll_table_struct *pt)
  407. {
  408. struct sdtx_client *client = file->private_data;
  409. __poll_t events = 0;
  410. if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &client->ddev->flags))
  411. return EPOLLHUP | EPOLLERR;
  412. poll_wait(file, &client->ddev->waitq, pt);
  413. if (!kfifo_is_empty(&client->buffer))
  414. events |= EPOLLIN | EPOLLRDNORM;
  415. return events;
  416. }
  417. static int surface_dtx_fasync(int fd, struct file *file, int on)
  418. {
  419. struct sdtx_client *client = file->private_data;
  420. return fasync_helper(fd, file, on, &client->fasync);
  421. }
  422. static const struct file_operations surface_dtx_fops = {
  423. .owner = THIS_MODULE,
  424. .open = surface_dtx_open,
  425. .release = surface_dtx_release,
  426. .read = surface_dtx_read,
  427. .poll = surface_dtx_poll,
  428. .fasync = surface_dtx_fasync,
  429. .unlocked_ioctl = surface_dtx_ioctl,
  430. .compat_ioctl = surface_dtx_ioctl,
  431. };
  432. /* -- Event handling/forwarding. -------------------------------------------- */
  433. /*
  434. * The device operation mode is not immediately updated on the EC when the
  435. * base has been connected, i.e. querying the device mode inside the
  436. * connection event callback yields an outdated value. Thus, we can only
  437. * determine the new tablet-mode switch and device mode values after some
  438. * time.
  439. *
  440. * These delays have been chosen by experimenting. We first delay on connect
  441. * events, then check and validate the device mode against the base state and
  442. * if invalid delay again by the "recheck" delay.
  443. */
  444. #define SDTX_DEVICE_MODE_DELAY_CONNECT msecs_to_jiffies(100)
  445. #define SDTX_DEVICE_MODE_DELAY_RECHECK msecs_to_jiffies(100)
  446. struct sdtx_status_event {
  447. struct sdtx_event e;
  448. __u16 v;
  449. } __packed;
  450. struct sdtx_base_info_event {
  451. struct sdtx_event e;
  452. struct sdtx_base_info v;
  453. } __packed;
  454. union sdtx_generic_event {
  455. struct sdtx_event common;
  456. struct sdtx_status_event status;
  457. struct sdtx_base_info_event base;
  458. };
  459. static void sdtx_update_device_mode(struct sdtx_device *ddev, unsigned long delay);
  460. /* Must be executed with ddev->write_lock held. */
  461. static void sdtx_push_event(struct sdtx_device *ddev, struct sdtx_event *evt)
  462. {
  463. const size_t len = sizeof(struct sdtx_event) + evt->length;
  464. struct sdtx_client *client;
  465. lockdep_assert_held(&ddev->write_lock);
  466. down_read(&ddev->client_lock);
  467. list_for_each_entry(client, &ddev->client_list, node) {
  468. if (!test_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags))
  469. continue;
  470. if (likely(kfifo_avail(&client->buffer) >= len))
  471. kfifo_in(&client->buffer, (const u8 *)evt, len);
  472. else
  473. dev_warn(ddev->dev, "event buffer overrun\n");
  474. kill_fasync(&client->fasync, SIGIO, POLL_IN);
  475. }
  476. up_read(&ddev->client_lock);
  477. wake_up_interruptible(&ddev->waitq);
  478. }
  479. static u32 sdtx_notifier(struct ssam_event_notifier *nf, const struct ssam_event *in)
  480. {
  481. struct sdtx_device *ddev = container_of(nf, struct sdtx_device, notif);
  482. union sdtx_generic_event event;
  483. size_t len;
  484. /* Validate event payload length. */
  485. switch (in->command_id) {
  486. case SAM_EVENT_CID_DTX_CONNECTION:
  487. len = 2 * sizeof(u8);
  488. break;
  489. case SAM_EVENT_CID_DTX_REQUEST:
  490. len = 0;
  491. break;
  492. case SAM_EVENT_CID_DTX_CANCEL:
  493. len = sizeof(u8);
  494. break;
  495. case SAM_EVENT_CID_DTX_LATCH_STATUS:
  496. len = sizeof(u8);
  497. break;
  498. default:
  499. return 0;
  500. }
  501. if (in->length != len) {
  502. dev_err(ddev->dev,
  503. "unexpected payload size for event %#04x: got %u, expected %zu\n",
  504. in->command_id, in->length, len);
  505. return 0;
  506. }
  507. mutex_lock(&ddev->write_lock);
  508. /* Translate event. */
  509. switch (in->command_id) {
  510. case SAM_EVENT_CID_DTX_CONNECTION:
  511. clear_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags);
  512. /* If state has not changed: do not send new event. */
  513. if (ddev->state.base.state == in->data[0] &&
  514. ddev->state.base.base_id == in->data[1])
  515. goto out;
  516. ddev->state.base.state = in->data[0];
  517. ddev->state.base.base_id = in->data[1];
  518. event.base.e.length = sizeof(struct sdtx_base_info);
  519. event.base.e.code = SDTX_EVENT_BASE_CONNECTION;
  520. event.base.v.state = sdtx_translate_base_state(ddev, in->data[0]);
  521. event.base.v.base_id = SDTX_BASE_TYPE_SSH(in->data[1]);
  522. break;
  523. case SAM_EVENT_CID_DTX_REQUEST:
  524. event.common.code = SDTX_EVENT_REQUEST;
  525. event.common.length = 0;
  526. break;
  527. case SAM_EVENT_CID_DTX_CANCEL:
  528. event.status.e.length = sizeof(u16);
  529. event.status.e.code = SDTX_EVENT_CANCEL;
  530. event.status.v = sdtx_translate_cancel_reason(ddev, in->data[0]);
  531. break;
  532. case SAM_EVENT_CID_DTX_LATCH_STATUS:
  533. clear_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags);
  534. /* If state has not changed: do not send new event. */
  535. if (ddev->state.latch_status == in->data[0])
  536. goto out;
  537. ddev->state.latch_status = in->data[0];
  538. event.status.e.length = sizeof(u16);
  539. event.status.e.code = SDTX_EVENT_LATCH_STATUS;
  540. event.status.v = sdtx_translate_latch_status(ddev, in->data[0]);
  541. break;
  542. }
  543. sdtx_push_event(ddev, &event.common);
  544. /* Update device mode on base connection change. */
  545. if (in->command_id == SAM_EVENT_CID_DTX_CONNECTION) {
  546. unsigned long delay;
  547. delay = in->data[0] ? SDTX_DEVICE_MODE_DELAY_CONNECT : 0;
  548. sdtx_update_device_mode(ddev, delay);
  549. }
  550. out:
  551. mutex_unlock(&ddev->write_lock);
  552. return SSAM_NOTIF_HANDLED;
  553. }
  554. /* -- State update functions. ----------------------------------------------- */
  555. static bool sdtx_device_mode_invalid(u8 mode, u8 base_state)
  556. {
  557. return ((base_state == SSAM_BAS_BASE_STATE_ATTACHED) &&
  558. (mode == SDTX_DEVICE_MODE_TABLET)) ||
  559. ((base_state == SSAM_BAS_BASE_STATE_DETACH_SUCCESS) &&
  560. (mode != SDTX_DEVICE_MODE_TABLET));
  561. }
  562. static void sdtx_device_mode_workfn(struct work_struct *work)
  563. {
  564. struct sdtx_device *ddev = container_of(work, struct sdtx_device, mode_work.work);
  565. struct sdtx_status_event event;
  566. struct ssam_bas_base_info base;
  567. int status, tablet;
  568. u8 mode;
  569. /* Get operation mode. */
  570. status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
  571. if (status) {
  572. dev_err(ddev->dev, "failed to get device mode: %d\n", status);
  573. return;
  574. }
  575. /* Get base info. */
  576. status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &base);
  577. if (status) {
  578. dev_err(ddev->dev, "failed to get base info: %d\n", status);
  579. return;
  580. }
  581. /*
  582. * In some cases (specifically when attaching the base), the device
  583. * mode isn't updated right away. Thus we check if the device mode
  584. * makes sense for the given base state and try again later if it
  585. * doesn't.
  586. */
  587. if (sdtx_device_mode_invalid(mode, base.state)) {
  588. dev_dbg(ddev->dev, "device mode is invalid, trying again\n");
  589. sdtx_update_device_mode(ddev, SDTX_DEVICE_MODE_DELAY_RECHECK);
  590. return;
  591. }
  592. mutex_lock(&ddev->write_lock);
  593. clear_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags);
  594. /* Avoid sending duplicate device-mode events. */
  595. if (ddev->state.device_mode == mode) {
  596. mutex_unlock(&ddev->write_lock);
  597. return;
  598. }
  599. ddev->state.device_mode = mode;
  600. event.e.length = sizeof(u16);
  601. event.e.code = SDTX_EVENT_DEVICE_MODE;
  602. event.v = mode;
  603. sdtx_push_event(ddev, &event.e);
  604. /* Send SW_TABLET_MODE event. */
  605. tablet = mode != SDTX_DEVICE_MODE_LAPTOP;
  606. input_report_switch(ddev->mode_switch, SW_TABLET_MODE, tablet);
  607. input_sync(ddev->mode_switch);
  608. mutex_unlock(&ddev->write_lock);
  609. }
  610. static void sdtx_update_device_mode(struct sdtx_device *ddev, unsigned long delay)
  611. {
  612. schedule_delayed_work(&ddev->mode_work, delay);
  613. }
  614. /* Must be executed with ddev->write_lock held. */
  615. static void __sdtx_device_state_update_base(struct sdtx_device *ddev,
  616. struct ssam_bas_base_info info)
  617. {
  618. struct sdtx_base_info_event event;
  619. lockdep_assert_held(&ddev->write_lock);
  620. /* Prevent duplicate events. */
  621. if (ddev->state.base.state == info.state &&
  622. ddev->state.base.base_id == info.base_id)
  623. return;
  624. ddev->state.base = info;
  625. event.e.length = sizeof(struct sdtx_base_info);
  626. event.e.code = SDTX_EVENT_BASE_CONNECTION;
  627. event.v.state = sdtx_translate_base_state(ddev, info.state);
  628. event.v.base_id = SDTX_BASE_TYPE_SSH(info.base_id);
  629. sdtx_push_event(ddev, &event.e);
  630. }
  631. /* Must be executed with ddev->write_lock held. */
  632. static void __sdtx_device_state_update_mode(struct sdtx_device *ddev, u8 mode)
  633. {
  634. struct sdtx_status_event event;
  635. int tablet;
  636. /*
  637. * Note: This function must be called after updating the base state
  638. * via __sdtx_device_state_update_base(), as we rely on the updated
  639. * base state value in the validity check below.
  640. */
  641. lockdep_assert_held(&ddev->write_lock);
  642. if (sdtx_device_mode_invalid(mode, ddev->state.base.state)) {
  643. dev_dbg(ddev->dev, "device mode is invalid, trying again\n");
  644. sdtx_update_device_mode(ddev, SDTX_DEVICE_MODE_DELAY_RECHECK);
  645. return;
  646. }
  647. /* Prevent duplicate events. */
  648. if (ddev->state.device_mode == mode)
  649. return;
  650. ddev->state.device_mode = mode;
  651. /* Send event. */
  652. event.e.length = sizeof(u16);
  653. event.e.code = SDTX_EVENT_DEVICE_MODE;
  654. event.v = mode;
  655. sdtx_push_event(ddev, &event.e);
  656. /* Send SW_TABLET_MODE event. */
  657. tablet = mode != SDTX_DEVICE_MODE_LAPTOP;
  658. input_report_switch(ddev->mode_switch, SW_TABLET_MODE, tablet);
  659. input_sync(ddev->mode_switch);
  660. }
  661. /* Must be executed with ddev->write_lock held. */
  662. static void __sdtx_device_state_update_latch(struct sdtx_device *ddev, u8 status)
  663. {
  664. struct sdtx_status_event event;
  665. lockdep_assert_held(&ddev->write_lock);
  666. /* Prevent duplicate events. */
  667. if (ddev->state.latch_status == status)
  668. return;
  669. ddev->state.latch_status = status;
  670. event.e.length = sizeof(struct sdtx_base_info);
  671. event.e.code = SDTX_EVENT_BASE_CONNECTION;
  672. event.v = sdtx_translate_latch_status(ddev, status);
  673. sdtx_push_event(ddev, &event.e);
  674. }
  675. static void sdtx_device_state_workfn(struct work_struct *work)
  676. {
  677. struct sdtx_device *ddev = container_of(work, struct sdtx_device, state_work.work);
  678. struct ssam_bas_base_info base;
  679. u8 mode, latch;
  680. int status;
  681. /* Mark everything as dirty. */
  682. set_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags);
  683. set_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags);
  684. set_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags);
  685. /*
  686. * Ensure that the state gets marked as dirty before continuing to
  687. * query it. Necessary to ensure that clear_bit() calls in
  688. * sdtx_notifier() and sdtx_device_mode_workfn() actually clear these
  689. * bits if an event is received while updating the state here.
  690. */
  691. smp_mb__after_atomic();
  692. status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &base);
  693. if (status) {
  694. dev_err(ddev->dev, "failed to get base state: %d\n", status);
  695. return;
  696. }
  697. status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
  698. if (status) {
  699. dev_err(ddev->dev, "failed to get device mode: %d\n", status);
  700. return;
  701. }
  702. status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &latch);
  703. if (status) {
  704. dev_err(ddev->dev, "failed to get latch status: %d\n", status);
  705. return;
  706. }
  707. mutex_lock(&ddev->write_lock);
  708. /*
  709. * If the respective dirty-bit has been cleared, an event has been
  710. * received, updating this state. The queried state may thus be out of
  711. * date. At this point, we can safely assume that the state provided
  712. * by the event is either up to date, or we're about to receive
  713. * another event updating it.
  714. */
  715. if (test_and_clear_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags))
  716. __sdtx_device_state_update_base(ddev, base);
  717. if (test_and_clear_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags))
  718. __sdtx_device_state_update_mode(ddev, mode);
  719. if (test_and_clear_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags))
  720. __sdtx_device_state_update_latch(ddev, latch);
  721. mutex_unlock(&ddev->write_lock);
  722. }
  723. static void sdtx_update_device_state(struct sdtx_device *ddev, unsigned long delay)
  724. {
  725. schedule_delayed_work(&ddev->state_work, delay);
  726. }
  727. /* -- Common device initialization. ----------------------------------------- */
  728. static int sdtx_device_init(struct sdtx_device *ddev, struct device *dev,
  729. struct ssam_controller *ctrl)
  730. {
  731. int status, tablet_mode;
  732. /* Basic initialization. */
  733. kref_init(&ddev->kref);
  734. init_rwsem(&ddev->lock);
  735. ddev->dev = dev;
  736. ddev->ctrl = ctrl;
  737. ddev->mdev.minor = MISC_DYNAMIC_MINOR;
  738. ddev->mdev.name = "surface_dtx";
  739. ddev->mdev.nodename = "surface/dtx";
  740. ddev->mdev.fops = &surface_dtx_fops;
  741. ddev->notif.base.priority = 1;
  742. ddev->notif.base.fn = sdtx_notifier;
  743. ddev->notif.event.reg = SSAM_EVENT_REGISTRY_SAM;
  744. ddev->notif.event.id.target_category = SSAM_SSH_TC_BAS;
  745. ddev->notif.event.id.instance = 0;
  746. ddev->notif.event.mask = SSAM_EVENT_MASK_NONE;
  747. ddev->notif.event.flags = SSAM_EVENT_SEQUENCED;
  748. init_waitqueue_head(&ddev->waitq);
  749. mutex_init(&ddev->write_lock);
  750. init_rwsem(&ddev->client_lock);
  751. INIT_LIST_HEAD(&ddev->client_list);
  752. INIT_DELAYED_WORK(&ddev->mode_work, sdtx_device_mode_workfn);
  753. INIT_DELAYED_WORK(&ddev->state_work, sdtx_device_state_workfn);
  754. /*
  755. * Get current device state. We want to guarantee that events are only
  756. * sent when state actually changes. Thus we cannot use special
  757. * "uninitialized" values, as that would cause problems when manually
  758. * querying the state in surface_dtx_pm_complete(). I.e. we would not
  759. * be able to detect state changes there if no change event has been
  760. * received between driver initialization and first device suspension.
  761. *
  762. * Note that we also need to do this before registering the event
  763. * notifier, as that may access the state values.
  764. */
  765. status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &ddev->state.base);
  766. if (status)
  767. return status;
  768. status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &ddev->state.device_mode);
  769. if (status)
  770. return status;
  771. status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &ddev->state.latch_status);
  772. if (status)
  773. return status;
  774. /* Set up tablet mode switch. */
  775. ddev->mode_switch = input_allocate_device();
  776. if (!ddev->mode_switch)
  777. return -ENOMEM;
  778. ddev->mode_switch->name = "Microsoft Surface DTX Device Mode Switch";
  779. ddev->mode_switch->phys = "ssam/01:11:01:00:00/input0";
  780. ddev->mode_switch->id.bustype = BUS_HOST;
  781. ddev->mode_switch->dev.parent = ddev->dev;
  782. tablet_mode = (ddev->state.device_mode != SDTX_DEVICE_MODE_LAPTOP);
  783. input_set_capability(ddev->mode_switch, EV_SW, SW_TABLET_MODE);
  784. input_report_switch(ddev->mode_switch, SW_TABLET_MODE, tablet_mode);
  785. status = input_register_device(ddev->mode_switch);
  786. if (status) {
  787. input_free_device(ddev->mode_switch);
  788. return status;
  789. }
  790. /* Set up event notifier. */
  791. status = ssam_notifier_register(ddev->ctrl, &ddev->notif);
  792. if (status)
  793. goto err_notif;
  794. /* Register miscdevice. */
  795. status = misc_register(&ddev->mdev);
  796. if (status)
  797. goto err_mdev;
  798. /*
  799. * Update device state in case it has changed between getting the
  800. * initial mode and registering the event notifier.
  801. */
  802. sdtx_update_device_state(ddev, 0);
  803. return 0;
  804. err_notif:
  805. ssam_notifier_unregister(ddev->ctrl, &ddev->notif);
  806. cancel_delayed_work_sync(&ddev->mode_work);
  807. err_mdev:
  808. input_unregister_device(ddev->mode_switch);
  809. return status;
  810. }
  811. static struct sdtx_device *sdtx_device_create(struct device *dev, struct ssam_controller *ctrl)
  812. {
  813. struct sdtx_device *ddev;
  814. int status;
  815. ddev = kzalloc_obj(*ddev);
  816. if (!ddev)
  817. return ERR_PTR(-ENOMEM);
  818. status = sdtx_device_init(ddev, dev, ctrl);
  819. if (status) {
  820. sdtx_device_put(ddev);
  821. return ERR_PTR(status);
  822. }
  823. return ddev;
  824. }
  825. static void sdtx_device_destroy(struct sdtx_device *ddev)
  826. {
  827. struct sdtx_client *client;
  828. /*
  829. * Mark device as shut-down. Prevent new clients from being added and
  830. * new operations from being executed.
  831. */
  832. set_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags);
  833. /* Disable notifiers, prevent new events from arriving. */
  834. ssam_notifier_unregister(ddev->ctrl, &ddev->notif);
  835. /* Stop mode_work, prevent access to mode_switch. */
  836. cancel_delayed_work_sync(&ddev->mode_work);
  837. /* Stop state_work. */
  838. cancel_delayed_work_sync(&ddev->state_work);
  839. /* With mode_work canceled, we can unregister the mode_switch. */
  840. input_unregister_device(ddev->mode_switch);
  841. /* Wake up async clients. */
  842. down_write(&ddev->client_lock);
  843. list_for_each_entry(client, &ddev->client_list, node) {
  844. kill_fasync(&client->fasync, SIGIO, POLL_HUP);
  845. }
  846. up_write(&ddev->client_lock);
  847. /* Wake up blocking clients. */
  848. wake_up_interruptible(&ddev->waitq);
  849. /*
  850. * Wait for clients to finish their current operation. After this, the
  851. * controller and device references are guaranteed to be no longer in
  852. * use.
  853. */
  854. down_write(&ddev->lock);
  855. ddev->dev = NULL;
  856. ddev->ctrl = NULL;
  857. up_write(&ddev->lock);
  858. /* Finally remove the misc-device. */
  859. misc_deregister(&ddev->mdev);
  860. /*
  861. * We're now guaranteed that sdtx_device_open() won't be called any
  862. * more, so we can now drop out reference.
  863. */
  864. sdtx_device_put(ddev);
  865. }
  866. /* -- PM ops. --------------------------------------------------------------- */
  867. #ifdef CONFIG_PM_SLEEP
  868. static void surface_dtx_pm_complete(struct device *dev)
  869. {
  870. struct sdtx_device *ddev = dev_get_drvdata(dev);
  871. /*
  872. * Normally, the EC will store events while suspended (i.e. in
  873. * display-off state) and release them when resumed (i.e. transitioned
  874. * to display-on state). During hibernation, however, the EC will be
  875. * shut down and does not store events. Furthermore, events might be
  876. * dropped during prolonged suspension (it is currently unknown how
  877. * big this event buffer is and how it behaves on overruns).
  878. *
  879. * To prevent any problems, we update the device state here. We do
  880. * this delayed to ensure that any events sent by the EC directly
  881. * after resuming will be handled first. The delay below has been
  882. * chosen (experimentally), so that there should be ample time for
  883. * these events to be handled, before we check and, if necessary,
  884. * update the state.
  885. */
  886. sdtx_update_device_state(ddev, msecs_to_jiffies(1000));
  887. }
  888. static const struct dev_pm_ops surface_dtx_pm_ops = {
  889. .complete = surface_dtx_pm_complete,
  890. };
  891. #else /* CONFIG_PM_SLEEP */
  892. static const struct dev_pm_ops surface_dtx_pm_ops = {};
  893. #endif /* CONFIG_PM_SLEEP */
  894. /* -- Platform driver. ------------------------------------------------------ */
  895. static int surface_dtx_platform_probe(struct platform_device *pdev)
  896. {
  897. struct ssam_controller *ctrl;
  898. struct sdtx_device *ddev;
  899. /* Link to EC. */
  900. ctrl = ssam_client_bind(&pdev->dev);
  901. if (IS_ERR(ctrl))
  902. return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);
  903. ddev = sdtx_device_create(&pdev->dev, ctrl);
  904. if (IS_ERR(ddev))
  905. return PTR_ERR(ddev);
  906. platform_set_drvdata(pdev, ddev);
  907. return 0;
  908. }
  909. static void surface_dtx_platform_remove(struct platform_device *pdev)
  910. {
  911. sdtx_device_destroy(platform_get_drvdata(pdev));
  912. }
  913. static const struct acpi_device_id surface_dtx_acpi_match[] = {
  914. { "MSHW0133", 0 },
  915. { },
  916. };
  917. MODULE_DEVICE_TABLE(acpi, surface_dtx_acpi_match);
  918. static struct platform_driver surface_dtx_platform_driver = {
  919. .probe = surface_dtx_platform_probe,
  920. .remove = surface_dtx_platform_remove,
  921. .driver = {
  922. .name = "surface_dtx_pltf",
  923. .acpi_match_table = surface_dtx_acpi_match,
  924. .pm = &surface_dtx_pm_ops,
  925. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  926. },
  927. };
  928. /* -- SSAM device driver. --------------------------------------------------- */
  929. #ifdef CONFIG_SURFACE_AGGREGATOR_BUS
  930. static int surface_dtx_ssam_probe(struct ssam_device *sdev)
  931. {
  932. struct sdtx_device *ddev;
  933. ddev = sdtx_device_create(&sdev->dev, sdev->ctrl);
  934. if (IS_ERR(ddev))
  935. return PTR_ERR(ddev);
  936. ssam_device_set_drvdata(sdev, ddev);
  937. return 0;
  938. }
  939. static void surface_dtx_ssam_remove(struct ssam_device *sdev)
  940. {
  941. sdtx_device_destroy(ssam_device_get_drvdata(sdev));
  942. }
  943. static const struct ssam_device_id surface_dtx_ssam_match[] = {
  944. { SSAM_SDEV(BAS, SAM, 0x00, 0x00) },
  945. { },
  946. };
  947. MODULE_DEVICE_TABLE(ssam, surface_dtx_ssam_match);
  948. static struct ssam_device_driver surface_dtx_ssam_driver = {
  949. .probe = surface_dtx_ssam_probe,
  950. .remove = surface_dtx_ssam_remove,
  951. .match_table = surface_dtx_ssam_match,
  952. .driver = {
  953. .name = "surface_dtx",
  954. .pm = &surface_dtx_pm_ops,
  955. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  956. },
  957. };
  958. static int ssam_dtx_driver_register(void)
  959. {
  960. return ssam_device_driver_register(&surface_dtx_ssam_driver);
  961. }
  962. static void ssam_dtx_driver_unregister(void)
  963. {
  964. ssam_device_driver_unregister(&surface_dtx_ssam_driver);
  965. }
  966. #else /* CONFIG_SURFACE_AGGREGATOR_BUS */
  967. static int ssam_dtx_driver_register(void)
  968. {
  969. return 0;
  970. }
  971. static void ssam_dtx_driver_unregister(void)
  972. {
  973. }
  974. #endif /* CONFIG_SURFACE_AGGREGATOR_BUS */
  975. /* -- Module setup. --------------------------------------------------------- */
  976. static int __init surface_dtx_init(void)
  977. {
  978. int status;
  979. status = ssam_dtx_driver_register();
  980. if (status)
  981. return status;
  982. status = platform_driver_register(&surface_dtx_platform_driver);
  983. if (status)
  984. ssam_dtx_driver_unregister();
  985. return status;
  986. }
  987. module_init(surface_dtx_init);
  988. static void __exit surface_dtx_exit(void)
  989. {
  990. platform_driver_unregister(&surface_dtx_platform_driver);
  991. ssam_dtx_driver_unregister();
  992. }
  993. module_exit(surface_dtx_exit);
  994. MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
  995. MODULE_DESCRIPTION("Detachment-system driver for Surface System Aggregator Module");
  996. MODULE_LICENSE("GPL");