reset-eyeq.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Reset driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms.
  4. *
  5. * Controllers live in a shared register region called OLB. EyeQ5 and EyeQ6L
  6. * have a single OLB instance for a single reset controller. EyeQ6H has seven
  7. * OLB instances; three host reset controllers.
  8. *
  9. * Each reset controller has one or more domain. Domains are of a given type
  10. * (see enum eqr_domain_type), with a valid offset mask (up to 32 resets per
  11. * domain).
  12. *
  13. * Domain types define expected behavior: one-register-per-reset,
  14. * one-bit-per-reset, status detection method, busywait duration, etc.
  15. *
  16. * We use eqr_ as prefix, as-in "EyeQ Reset", but way shorter.
  17. *
  18. * Known resets in EyeQ5 domain 0 (type EQR_EYEQ5_SARCR):
  19. * 3. CAN0 4. CAN1 5. CAN2 6. SPI0
  20. * 7. SPI1 8. SPI2 9. SPI3 10. UART0
  21. * 11. UART1 12. UART2 13. I2C0 14. I2C1
  22. * 15. I2C2 16. I2C3 17. I2C4 18. TIMER0
  23. * 19. TIMER1 20. TIMER2 21. TIMER3 22. TIMER4
  24. * 23. WD0 24. EXT0 25. EXT1 26. GPIO
  25. * 27. WD1
  26. *
  27. * Known resets in EyeQ5 domain 1 (type EQR_EYEQ5_ACRP):
  28. * 0. VMP0 1. VMP1 2. VMP2 3. VMP3
  29. * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1
  30. * 8. MPC0 9. MPC1 10. MPC2 11. MPC3
  31. * 12. MPC4
  32. *
  33. * Known resets in EyeQ5 domain 2 (type EQR_EYEQ5_PCIE):
  34. * 0. PCIE0_CORE 1. PCIE0_APB 2. PCIE0_LINK_AXI 3. PCIE0_LINK_MGMT
  35. * 4. PCIE0_LINK_HOT 5. PCIE0_LINK_PIPE 6. PCIE1_CORE 7. PCIE1_APB
  36. * 8. PCIE1_LINK_AXI 9. PCIE1_LINK_MGMT 10. PCIE1_LINK_HOT 11. PCIE1_LINK_PIPE
  37. * 12. MULTIPHY 13. MULTIPHY_APB 15. PCIE0_LINK_MGMT 16. PCIE1_LINK_MGMT
  38. * 17. PCIE0_LINK_PM 18. PCIE1_LINK_PM
  39. *
  40. * Known resets in EyeQ6L domain 0 (type EQR_EYEQ5_SARCR):
  41. * 0. SPI0 1. SPI1 2. UART0 3. I2C0
  42. * 4. I2C1 5. TIMER0 6. TIMER1 7. TIMER2
  43. * 8. TIMER3 9. WD0 10. WD1 11. EXT0
  44. * 12. EXT1 13. GPIO
  45. *
  46. * Known resets in EyeQ6L domain 1 (type EQR_EYEQ5_ACRP):
  47. * 0. VMP0 1. VMP1 2. VMP2 3. VMP3
  48. * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1
  49. * 8. MPC0 9. MPC1 10. MPC2 11. MPC3
  50. * 12. MPC4
  51. *
  52. * Known resets in EyeQ6H west/east (type EQR_EYEQ6H_SARCR):
  53. * 0. CAN 1. SPI0 2. SPI1 3. UART0
  54. * 4. UART1 5. I2C0 6. I2C1 7. -hole-
  55. * 8. TIMER0 9. TIMER1 10. WD 11. EXT TIMER
  56. * 12. GPIO
  57. *
  58. * Known resets in EyeQ6H acc (type EQR_EYEQ5_ACRP):
  59. * 1. XNN0 2. XNN1 3. XNN2 4. XNN3
  60. * 5. VMP0 6. VMP1 7. VMP2 8. VMP3
  61. * 9. PMA0 10. PMA1 11. MPC0 12. MPC1
  62. * 13. MPC2 14. MPC3 15. PERIPH
  63. *
  64. * Abbreviations:
  65. * - PMA: Programmable Macro Array
  66. * - MPC: Multi-threaded Processing Clusters
  67. * - VMP: Vector Microcode Processors
  68. *
  69. * Copyright (C) 2024 Mobileye Vision Technologies Ltd.
  70. */
  71. #include <linux/array_size.h>
  72. #include <linux/auxiliary_bus.h>
  73. #include <linux/bitfield.h>
  74. #include <linux/bits.h>
  75. #include <linux/bug.h>
  76. #include <linux/cleanup.h>
  77. #include <linux/container_of.h>
  78. #include <linux/device.h>
  79. #include <linux/err.h>
  80. #include <linux/errno.h>
  81. #include <linux/init.h>
  82. #include <linux/io.h>
  83. #include <linux/iopoll.h>
  84. #include <linux/lockdep.h>
  85. #include <linux/mod_devicetable.h>
  86. #include <linux/mutex.h>
  87. #include <linux/of.h>
  88. #include <linux/reset-controller.h>
  89. #include <linux/slab.h>
  90. #include <linux/types.h>
  91. /*
  92. * A reset ID, as returned by eqr_of_xlate_*(), is a (domain, offset) pair.
  93. * Low byte is domain, rest is offset.
  94. */
  95. #define ID_DOMAIN_MASK GENMASK(7, 0)
  96. #define ID_OFFSET_MASK GENMASK(31, 8)
  97. enum eqr_domain_type {
  98. EQR_EYEQ5_SARCR,
  99. EQR_EYEQ5_ACRP,
  100. EQR_EYEQ5_PCIE,
  101. EQR_EYEQ6H_SARCR,
  102. };
  103. /*
  104. * Domain type EQR_EYEQ5_SARCR register offsets.
  105. */
  106. #define EQR_EYEQ5_SARCR_REQUEST (0x000)
  107. #define EQR_EYEQ5_SARCR_STATUS (0x004)
  108. /*
  109. * Domain type EQR_EYEQ5_ACRP register masks.
  110. * Registers are: base + 4 * offset.
  111. */
  112. #define EQR_EYEQ5_ACRP_PD_REQ BIT(0)
  113. #define EQR_EYEQ5_ACRP_ST_POWER_DOWN BIT(27)
  114. #define EQR_EYEQ5_ACRP_ST_ACTIVE BIT(29)
  115. /*
  116. * Domain type EQR_EYEQ6H_SARCR register offsets.
  117. */
  118. #define EQR_EYEQ6H_SARCR_RST_REQUEST (0x000)
  119. #define EQR_EYEQ6H_SARCR_CLK_STATUS (0x004)
  120. #define EQR_EYEQ6H_SARCR_RST_STATUS (0x008)
  121. #define EQR_EYEQ6H_SARCR_CLK_REQUEST (0x00C)
  122. struct eqr_busy_wait_timings {
  123. unsigned long sleep_us;
  124. unsigned long timeout_us;
  125. };
  126. static const struct eqr_busy_wait_timings eqr_timings[] = {
  127. [EQR_EYEQ5_SARCR] = {1, 10},
  128. [EQR_EYEQ5_ACRP] = {1, 40 * USEC_PER_MSEC}, /* LBIST implies long timeout. */
  129. /* EQR_EYEQ5_PCIE does no busy waiting. */
  130. [EQR_EYEQ6H_SARCR] = {1, 400},
  131. };
  132. #define EQR_MAX_DOMAIN_COUNT 3
  133. struct eqr_domain_descriptor {
  134. enum eqr_domain_type type;
  135. u32 valid_mask;
  136. unsigned int offset;
  137. };
  138. struct eqr_match_data {
  139. unsigned int domain_count;
  140. const struct eqr_domain_descriptor *domains;
  141. };
  142. struct eqr_private {
  143. /*
  144. * One mutex per domain for read-modify-write operations on registers.
  145. * Some domains can be involved in LBIST which implies long critical
  146. * sections; we wouldn't want other domains to be impacted by that.
  147. */
  148. struct mutex mutexes[EQR_MAX_DOMAIN_COUNT];
  149. void __iomem *base;
  150. const struct eqr_match_data *data;
  151. struct reset_controller_dev rcdev;
  152. };
  153. static inline struct eqr_private *eqr_rcdev_to_priv(struct reset_controller_dev *x)
  154. {
  155. return container_of(x, struct eqr_private, rcdev);
  156. }
  157. static u32 eqr_double_readl(void __iomem *addr_a, void __iomem *addr_b,
  158. u32 *dest_a, u32 *dest_b)
  159. {
  160. *dest_a = readl(addr_a);
  161. *dest_b = readl(addr_b);
  162. return 0; /* read_poll_timeout() op argument must return something. */
  163. }
  164. static int eqr_busy_wait_locked(struct eqr_private *priv, struct device *dev,
  165. u32 domain, u32 offset, bool assert)
  166. {
  167. void __iomem *base = priv->base + priv->data->domains[domain].offset;
  168. enum eqr_domain_type domain_type = priv->data->domains[domain].type;
  169. unsigned long timeout_us = eqr_timings[domain_type].timeout_us;
  170. unsigned long sleep_us = eqr_timings[domain_type].sleep_us;
  171. u32 val, mask, rst_status, clk_status;
  172. void __iomem *reg;
  173. int ret;
  174. lockdep_assert_held(&priv->mutexes[domain]);
  175. switch (domain_type) {
  176. case EQR_EYEQ5_SARCR:
  177. reg = base + EQR_EYEQ5_SARCR_STATUS;
  178. mask = BIT(offset);
  179. ret = readl_poll_timeout(reg, val, !(val & mask) == assert,
  180. sleep_us, timeout_us);
  181. break;
  182. case EQR_EYEQ5_ACRP:
  183. reg = base + 4 * offset;
  184. if (assert)
  185. mask = EQR_EYEQ5_ACRP_ST_POWER_DOWN;
  186. else
  187. mask = EQR_EYEQ5_ACRP_ST_ACTIVE;
  188. ret = readl_poll_timeout(reg, val, !!(val & mask),
  189. sleep_us, timeout_us);
  190. break;
  191. case EQR_EYEQ5_PCIE:
  192. ret = 0; /* No busy waiting. */
  193. break;
  194. case EQR_EYEQ6H_SARCR:
  195. /*
  196. * Wait until both bits change:
  197. * readl(base + EQR_EYEQ6H_SARCR_RST_STATUS) & BIT(offset)
  198. * readl(base + EQR_EYEQ6H_SARCR_CLK_STATUS) & BIT(offset)
  199. */
  200. mask = BIT(offset);
  201. ret = read_poll_timeout(eqr_double_readl, val,
  202. (!(rst_status & mask) == assert) &&
  203. (!(clk_status & mask) == assert),
  204. sleep_us, timeout_us, false,
  205. base + EQR_EYEQ6H_SARCR_RST_STATUS,
  206. base + EQR_EYEQ6H_SARCR_CLK_STATUS,
  207. &rst_status, &clk_status);
  208. break;
  209. default:
  210. WARN_ON(1);
  211. ret = -EINVAL;
  212. break;
  213. }
  214. if (ret == -ETIMEDOUT)
  215. dev_dbg(dev, "%u-%u: timeout\n", domain, offset);
  216. return ret;
  217. }
  218. static void eqr_assert_locked(struct eqr_private *priv, u32 domain, u32 offset)
  219. {
  220. enum eqr_domain_type domain_type = priv->data->domains[domain].type;
  221. void __iomem *base, *reg;
  222. u32 val;
  223. lockdep_assert_held(&priv->mutexes[domain]);
  224. base = priv->base + priv->data->domains[domain].offset;
  225. switch (domain_type) {
  226. case EQR_EYEQ5_SARCR:
  227. reg = base + EQR_EYEQ5_SARCR_REQUEST;
  228. writel(readl(reg) & ~BIT(offset), reg);
  229. break;
  230. case EQR_EYEQ5_ACRP:
  231. reg = base + 4 * offset;
  232. writel(readl(reg) | EQR_EYEQ5_ACRP_PD_REQ, reg);
  233. break;
  234. case EQR_EYEQ5_PCIE:
  235. writel(readl(base) & ~BIT(offset), base);
  236. break;
  237. case EQR_EYEQ6H_SARCR:
  238. /* RST_REQUEST and CLK_REQUEST must be kept in sync. */
  239. val = readl(base + EQR_EYEQ6H_SARCR_RST_REQUEST);
  240. val &= ~BIT(offset);
  241. writel(val, base + EQR_EYEQ6H_SARCR_RST_REQUEST);
  242. writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST);
  243. break;
  244. default:
  245. WARN_ON(1);
  246. break;
  247. }
  248. }
  249. static int eqr_assert(struct reset_controller_dev *rcdev, unsigned long id)
  250. {
  251. struct eqr_private *priv = eqr_rcdev_to_priv(rcdev);
  252. u32 domain = FIELD_GET(ID_DOMAIN_MASK, id);
  253. u32 offset = FIELD_GET(ID_OFFSET_MASK, id);
  254. dev_dbg(rcdev->dev, "%u-%u: assert request\n", domain, offset);
  255. guard(mutex)(&priv->mutexes[domain]);
  256. eqr_assert_locked(priv, domain, offset);
  257. return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, true);
  258. }
  259. static void eqr_deassert_locked(struct eqr_private *priv, u32 domain,
  260. u32 offset)
  261. {
  262. enum eqr_domain_type domain_type = priv->data->domains[domain].type;
  263. void __iomem *base, *reg;
  264. u32 val;
  265. lockdep_assert_held(&priv->mutexes[domain]);
  266. base = priv->base + priv->data->domains[domain].offset;
  267. switch (domain_type) {
  268. case EQR_EYEQ5_SARCR:
  269. reg = base + EQR_EYEQ5_SARCR_REQUEST;
  270. writel(readl(reg) | BIT(offset), reg);
  271. break;
  272. case EQR_EYEQ5_ACRP:
  273. reg = base + 4 * offset;
  274. writel(readl(reg) & ~EQR_EYEQ5_ACRP_PD_REQ, reg);
  275. break;
  276. case EQR_EYEQ5_PCIE:
  277. writel(readl(base) | BIT(offset), base);
  278. break;
  279. case EQR_EYEQ6H_SARCR:
  280. /* RST_REQUEST and CLK_REQUEST must be kept in sync. */
  281. val = readl(base + EQR_EYEQ6H_SARCR_RST_REQUEST);
  282. val |= BIT(offset);
  283. writel(val, base + EQR_EYEQ6H_SARCR_RST_REQUEST);
  284. writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST);
  285. break;
  286. default:
  287. WARN_ON(1);
  288. break;
  289. }
  290. }
  291. static int eqr_deassert(struct reset_controller_dev *rcdev, unsigned long id)
  292. {
  293. struct eqr_private *priv = eqr_rcdev_to_priv(rcdev);
  294. u32 domain = FIELD_GET(ID_DOMAIN_MASK, id);
  295. u32 offset = FIELD_GET(ID_OFFSET_MASK, id);
  296. dev_dbg(rcdev->dev, "%u-%u: deassert request\n", domain, offset);
  297. guard(mutex)(&priv->mutexes[domain]);
  298. eqr_deassert_locked(priv, domain, offset);
  299. return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, false);
  300. }
  301. static int eqr_status(struct reset_controller_dev *rcdev, unsigned long id)
  302. {
  303. u32 domain = FIELD_GET(ID_DOMAIN_MASK, id);
  304. u32 offset = FIELD_GET(ID_OFFSET_MASK, id);
  305. struct eqr_private *priv = eqr_rcdev_to_priv(rcdev);
  306. enum eqr_domain_type domain_type = priv->data->domains[domain].type;
  307. void __iomem *base, *reg;
  308. dev_dbg(rcdev->dev, "%u-%u: status request\n", domain, offset);
  309. guard(mutex)(&priv->mutexes[domain]);
  310. base = priv->base + priv->data->domains[domain].offset;
  311. switch (domain_type) {
  312. case EQR_EYEQ5_SARCR:
  313. reg = base + EQR_EYEQ5_SARCR_STATUS;
  314. return !(readl(reg) & BIT(offset));
  315. case EQR_EYEQ5_ACRP:
  316. reg = base + 4 * offset;
  317. return !(readl(reg) & EQR_EYEQ5_ACRP_ST_ACTIVE);
  318. case EQR_EYEQ5_PCIE:
  319. return !(readl(base) & BIT(offset));
  320. case EQR_EYEQ6H_SARCR:
  321. reg = base + EQR_EYEQ6H_SARCR_RST_STATUS;
  322. return !(readl(reg) & BIT(offset));
  323. default:
  324. return -EINVAL;
  325. }
  326. }
  327. static const struct reset_control_ops eqr_ops = {
  328. .assert = eqr_assert,
  329. .deassert = eqr_deassert,
  330. .status = eqr_status,
  331. };
  332. static int eqr_of_xlate_internal(struct reset_controller_dev *rcdev,
  333. u32 domain, u32 offset)
  334. {
  335. struct eqr_private *priv = eqr_rcdev_to_priv(rcdev);
  336. if (domain >= priv->data->domain_count || offset > 31 ||
  337. !(priv->data->domains[domain].valid_mask & BIT(offset))) {
  338. dev_err(rcdev->dev, "%u-%u: invalid reset\n", domain, offset);
  339. return -EINVAL;
  340. }
  341. return FIELD_PREP(ID_DOMAIN_MASK, domain) | FIELD_PREP(ID_OFFSET_MASK, offset);
  342. }
  343. static int eqr_of_xlate_onecell(struct reset_controller_dev *rcdev,
  344. const struct of_phandle_args *reset_spec)
  345. {
  346. return eqr_of_xlate_internal(rcdev, 0, reset_spec->args[0]);
  347. }
  348. static int eqr_of_xlate_twocells(struct reset_controller_dev *rcdev,
  349. const struct of_phandle_args *reset_spec)
  350. {
  351. return eqr_of_xlate_internal(rcdev, reset_spec->args[0], reset_spec->args[1]);
  352. }
  353. static void eqr_of_node_put(void *_dev)
  354. {
  355. struct device *dev = _dev;
  356. of_node_put(dev->of_node);
  357. }
  358. static int eqr_probe(struct auxiliary_device *adev,
  359. const struct auxiliary_device_id *id)
  360. {
  361. const struct of_device_id *match;
  362. struct device *dev = &adev->dev;
  363. struct eqr_private *priv;
  364. unsigned int i;
  365. int ret;
  366. /*
  367. * We are an auxiliary device of clk-eyeq. We do not have an OF node by
  368. * default; let's reuse our parent's OF node.
  369. */
  370. WARN_ON(dev->of_node);
  371. device_set_of_node_from_dev(dev, dev->parent);
  372. if (!dev->of_node)
  373. return -ENODEV;
  374. ret = devm_add_action_or_reset(dev, eqr_of_node_put, dev);
  375. if (ret)
  376. return ret;
  377. /*
  378. * Using our newfound OF node, we can get match data. We cannot use
  379. * device_get_match_data() because it does not match reused OF nodes.
  380. */
  381. match = of_match_node(dev->driver->of_match_table, dev->of_node);
  382. if (!match || !match->data)
  383. return -ENODEV;
  384. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  385. if (!priv)
  386. return -ENOMEM;
  387. priv->data = match->data;
  388. priv->base = (void __iomem *)dev_get_platdata(dev);
  389. priv->rcdev.ops = &eqr_ops;
  390. priv->rcdev.owner = THIS_MODULE;
  391. priv->rcdev.dev = dev;
  392. priv->rcdev.of_node = dev->of_node;
  393. if (priv->data->domain_count == 1) {
  394. priv->rcdev.of_reset_n_cells = 1;
  395. priv->rcdev.of_xlate = eqr_of_xlate_onecell;
  396. } else {
  397. priv->rcdev.of_reset_n_cells = 2;
  398. priv->rcdev.of_xlate = eqr_of_xlate_twocells;
  399. }
  400. for (i = 0; i < priv->data->domain_count; i++)
  401. mutex_init(&priv->mutexes[i]);
  402. priv->rcdev.nr_resets = 0;
  403. for (i = 0; i < priv->data->domain_count; i++)
  404. priv->rcdev.nr_resets += hweight32(priv->data->domains[i].valid_mask);
  405. ret = devm_reset_controller_register(dev, &priv->rcdev);
  406. if (ret)
  407. return dev_err_probe(dev, ret, "failed registering reset controller\n");
  408. return 0;
  409. }
  410. static const struct eqr_domain_descriptor eqr_eyeq5_domains[] = {
  411. {
  412. .type = EQR_EYEQ5_SARCR,
  413. .valid_mask = 0xFFFFFF8,
  414. .offset = 0x004,
  415. },
  416. {
  417. .type = EQR_EYEQ5_ACRP,
  418. .valid_mask = 0x0001FFF,
  419. .offset = 0x200,
  420. },
  421. {
  422. .type = EQR_EYEQ5_PCIE,
  423. .valid_mask = 0x007BFFF,
  424. .offset = 0x120,
  425. },
  426. };
  427. static const struct eqr_match_data eqr_eyeq5_data = {
  428. .domain_count = ARRAY_SIZE(eqr_eyeq5_domains),
  429. .domains = eqr_eyeq5_domains,
  430. };
  431. static const struct eqr_domain_descriptor eqr_eyeq6l_domains[] = {
  432. {
  433. .type = EQR_EYEQ5_SARCR,
  434. .valid_mask = 0x3FFF,
  435. .offset = 0x004,
  436. },
  437. {
  438. .type = EQR_EYEQ5_ACRP,
  439. .valid_mask = 0x00FF,
  440. .offset = 0x200,
  441. },
  442. };
  443. static const struct eqr_match_data eqr_eyeq6l_data = {
  444. .domain_count = ARRAY_SIZE(eqr_eyeq6l_domains),
  445. .domains = eqr_eyeq6l_domains,
  446. };
  447. /* West and east OLBs each have an instance. */
  448. static const struct eqr_domain_descriptor eqr_eyeq6h_we_domains[] = {
  449. {
  450. .type = EQR_EYEQ6H_SARCR,
  451. .valid_mask = 0x1F7F,
  452. .offset = 0x004,
  453. },
  454. };
  455. static const struct eqr_match_data eqr_eyeq6h_we_data = {
  456. .domain_count = ARRAY_SIZE(eqr_eyeq6h_we_domains),
  457. .domains = eqr_eyeq6h_we_domains,
  458. };
  459. static const struct eqr_domain_descriptor eqr_eyeq6h_acc_domains[] = {
  460. {
  461. .type = EQR_EYEQ5_ACRP,
  462. .valid_mask = 0x7FFF,
  463. .offset = 0x000,
  464. },
  465. };
  466. static const struct eqr_match_data eqr_eyeq6h_acc_data = {
  467. .domain_count = ARRAY_SIZE(eqr_eyeq6h_acc_domains),
  468. .domains = eqr_eyeq6h_acc_domains,
  469. };
  470. /*
  471. * Table describes OLB system-controller compatibles.
  472. * It does not get used to match against devicetree node.
  473. */
  474. static const struct of_device_id eqr_match_table[] = {
  475. { .compatible = "mobileye,eyeq5-olb", .data = &eqr_eyeq5_data },
  476. { .compatible = "mobileye,eyeq6l-olb", .data = &eqr_eyeq6l_data },
  477. { .compatible = "mobileye,eyeq6h-west-olb", .data = &eqr_eyeq6h_we_data },
  478. { .compatible = "mobileye,eyeq6h-east-olb", .data = &eqr_eyeq6h_we_data },
  479. { .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqr_eyeq6h_acc_data },
  480. {}
  481. };
  482. MODULE_DEVICE_TABLE(of, eqr_match_table);
  483. static const struct auxiliary_device_id eqr_id_table[] = {
  484. { .name = "clk_eyeq.reset" },
  485. { .name = "clk_eyeq.reset_west" },
  486. { .name = "clk_eyeq.reset_east" },
  487. { .name = "clk_eyeq.reset_acc" },
  488. {}
  489. };
  490. MODULE_DEVICE_TABLE(auxiliary, eqr_id_table);
  491. static struct auxiliary_driver eqr_driver = {
  492. .probe = eqr_probe,
  493. .id_table = eqr_id_table,
  494. .driver = {
  495. .of_match_table = eqr_match_table,
  496. }
  497. };
  498. module_auxiliary_driver(eqr_driver);