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 EyeQ6Lplus domain 0 (type EQR_EYEQ5_PCIE): 53 * 0. SPI0 1. SPI1 2. UART0 3. I2C0 54 * 4. I2C1 5. TIMER0 6. TIMER1 7. TIMER2 55 * 8. TIMER3 9. WD0 10. WD1 11. EXT0 56 * 12. EXT1 13. GPIO 57 * 58 * Known resets in EyeQ6Lplus domain 1 (type EQR_EYEQ5_ACRP): 59 * 0. VMP0 1. VMP1 2. VMP2 3. VMP3 60 * 4. PMA0 5. PMA1 6. PMAC0 7. PMAC1 61 * 8. MPC0 9. MPC1 10. MPC2 11. MPC3 62 * 12. MPC4 63 * 64 * Known resets in EyeQ6H west/east (type EQR_EYEQ6H_SARCR): 65 * 0. CAN 1. SPI0 2. SPI1 3. UART0 66 * 4. UART1 5. I2C0 6. I2C1 7. -hole- 67 * 8. TIMER0 9. TIMER1 10. WD 11. EXT TIMER 68 * 12. GPIO 69 * 70 * Known resets in EyeQ6H acc (type EQR_EYEQ5_ACRP): 71 * 1. XNN0 2. XNN1 3. XNN2 4. XNN3 72 * 5. VMP0 6. VMP1 7. VMP2 8. VMP3 73 * 9. PMA0 10. PMA1 11. MPC0 12. MPC1 74 * 13. MPC2 14. MPC3 15. PERIPH 75 * 76 * Abbreviations: 77 * - PMA: Programmable Macro Array 78 * - MPC: Multi-threaded Processing Clusters 79 * - VMP: Vector Microcode Processors 80 * 81 * Copyright (C) 2024 Mobileye Vision Technologies Ltd. 82 */ 83 84 #include <linux/array_size.h> 85 #include <linux/auxiliary_bus.h> 86 #include <linux/bitfield.h> 87 #include <linux/bits.h> 88 #include <linux/bug.h> 89 #include <linux/cleanup.h> 90 #include <linux/container_of.h> 91 #include <linux/device.h> 92 #include <linux/err.h> 93 #include <linux/errno.h> 94 #include <linux/init.h> 95 #include <linux/io.h> 96 #include <linux/iopoll.h> 97 #include <linux/lockdep.h> 98 #include <linux/mutex.h> 99 #include <linux/of.h> 100 #include <linux/reset-controller.h> 101 #include <linux/slab.h> 102 #include <linux/types.h> 103 104 /* 105 * A reset ID, as returned by eqr_of_xlate_*(), is a (domain, offset) pair. 106 * Low byte is domain, rest is offset. 107 */ 108 #define ID_DOMAIN_MASK GENMASK(7, 0) 109 #define ID_OFFSET_MASK GENMASK(31, 8) 110 111 enum eqr_domain_type { 112 EQR_EYEQ5_SARCR, 113 EQR_EYEQ5_ACRP, 114 EQR_EYEQ5_PCIE, 115 EQR_EYEQ6H_SARCR, 116 }; 117 118 /* 119 * Domain type EQR_EYEQ5_SARCR register offsets. 120 */ 121 #define EQR_EYEQ5_SARCR_REQUEST (0x000) 122 #define EQR_EYEQ5_SARCR_STATUS (0x004) 123 124 /* 125 * Domain type EQR_EYEQ5_ACRP register masks. 126 * Registers are: base + 4 * offset. 127 */ 128 #define EQR_EYEQ5_ACRP_PD_REQ BIT(0) 129 #define EQR_EYEQ5_ACRP_ST_POWER_DOWN BIT(27) 130 #define EQR_EYEQ5_ACRP_ST_ACTIVE BIT(29) 131 132 /* 133 * Domain type EQR_EYEQ6H_SARCR register offsets. 134 */ 135 #define EQR_EYEQ6H_SARCR_RST_REQUEST (0x000) 136 #define EQR_EYEQ6H_SARCR_CLK_STATUS (0x004) 137 #define EQR_EYEQ6H_SARCR_RST_STATUS (0x008) 138 #define EQR_EYEQ6H_SARCR_CLK_REQUEST (0x00C) 139 140 struct eqr_busy_wait_timings { 141 unsigned long sleep_us; 142 unsigned long timeout_us; 143 }; 144 145 static const struct eqr_busy_wait_timings eqr_timings[] = { 146 [EQR_EYEQ5_SARCR] = {1, 10}, 147 [EQR_EYEQ5_ACRP] = {1, 40 * USEC_PER_MSEC}, /* LBIST implies long timeout. */ 148 /* EQR_EYEQ5_PCIE does no busy waiting. */ 149 [EQR_EYEQ6H_SARCR] = {1, 400}, 150 }; 151 152 #define EQR_MAX_DOMAIN_COUNT 3 153 154 struct eqr_domain_descriptor { 155 enum eqr_domain_type type; 156 u32 valid_mask; 157 unsigned int offset; 158 }; 159 160 struct eqr_match_data { 161 unsigned int domain_count; 162 const struct eqr_domain_descriptor *domains; 163 }; 164 165 struct eqr_private { 166 /* 167 * One mutex per domain for read-modify-write operations on registers. 168 * Some domains can be involved in LBIST which implies long critical 169 * sections; we wouldn't want other domains to be impacted by that. 170 */ 171 struct mutex mutexes[EQR_MAX_DOMAIN_COUNT]; 172 void __iomem *base; 173 const struct eqr_match_data *data; 174 struct reset_controller_dev rcdev; 175 }; 176 177 static inline struct eqr_private *eqr_rcdev_to_priv(struct reset_controller_dev *x) 178 { 179 return container_of(x, struct eqr_private, rcdev); 180 } 181 182 static u32 eqr_double_readl(void __iomem *addr_a, void __iomem *addr_b, 183 u32 *dest_a, u32 *dest_b) 184 { 185 *dest_a = readl(addr_a); 186 *dest_b = readl(addr_b); 187 return 0; /* read_poll_timeout() op argument must return something. */ 188 } 189 190 static int eqr_busy_wait_locked(struct eqr_private *priv, struct device *dev, 191 u32 domain, u32 offset, bool assert) 192 { 193 void __iomem *base = priv->base + priv->data->domains[domain].offset; 194 enum eqr_domain_type domain_type = priv->data->domains[domain].type; 195 unsigned long timeout_us = eqr_timings[domain_type].timeout_us; 196 unsigned long sleep_us = eqr_timings[domain_type].sleep_us; 197 u32 val, mask, rst_status, clk_status; 198 void __iomem *reg; 199 int ret; 200 201 lockdep_assert_held(&priv->mutexes[domain]); 202 203 switch (domain_type) { 204 case EQR_EYEQ5_SARCR: 205 reg = base + EQR_EYEQ5_SARCR_STATUS; 206 mask = BIT(offset); 207 208 ret = readl_poll_timeout(reg, val, !(val & mask) == assert, 209 sleep_us, timeout_us); 210 break; 211 212 case EQR_EYEQ5_ACRP: 213 reg = base + 4 * offset; 214 if (assert) 215 mask = EQR_EYEQ5_ACRP_ST_POWER_DOWN; 216 else 217 mask = EQR_EYEQ5_ACRP_ST_ACTIVE; 218 219 ret = readl_poll_timeout(reg, val, !!(val & mask), 220 sleep_us, timeout_us); 221 break; 222 223 case EQR_EYEQ5_PCIE: 224 ret = 0; /* No busy waiting. */ 225 break; 226 227 case EQR_EYEQ6H_SARCR: 228 /* 229 * Wait until both bits change: 230 * readl(base + EQR_EYEQ6H_SARCR_RST_STATUS) & BIT(offset) 231 * readl(base + EQR_EYEQ6H_SARCR_CLK_STATUS) & BIT(offset) 232 */ 233 mask = BIT(offset); 234 ret = read_poll_timeout(eqr_double_readl, val, 235 (!(rst_status & mask) == assert) && 236 (!(clk_status & mask) == assert), 237 sleep_us, timeout_us, false, 238 base + EQR_EYEQ6H_SARCR_RST_STATUS, 239 base + EQR_EYEQ6H_SARCR_CLK_STATUS, 240 &rst_status, &clk_status); 241 break; 242 243 default: 244 WARN_ON(1); 245 ret = -EINVAL; 246 break; 247 } 248 249 if (ret == -ETIMEDOUT) 250 dev_dbg(dev, "%u-%u: timeout\n", domain, offset); 251 return ret; 252 } 253 254 static void eqr_assert_locked(struct eqr_private *priv, u32 domain, u32 offset) 255 { 256 enum eqr_domain_type domain_type = priv->data->domains[domain].type; 257 void __iomem *base, *reg; 258 u32 val; 259 260 lockdep_assert_held(&priv->mutexes[domain]); 261 262 base = priv->base + priv->data->domains[domain].offset; 263 264 switch (domain_type) { 265 case EQR_EYEQ5_SARCR: 266 reg = base + EQR_EYEQ5_SARCR_REQUEST; 267 writel(readl(reg) & ~BIT(offset), reg); 268 break; 269 270 case EQR_EYEQ5_ACRP: 271 reg = base + 4 * offset; 272 writel(readl(reg) | EQR_EYEQ5_ACRP_PD_REQ, reg); 273 break; 274 275 case EQR_EYEQ5_PCIE: 276 writel(readl(base) & ~BIT(offset), base); 277 break; 278 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 287 default: 288 WARN_ON(1); 289 break; 290 } 291 } 292 293 static int eqr_assert(struct reset_controller_dev *rcdev, unsigned long id) 294 { 295 struct eqr_private *priv = eqr_rcdev_to_priv(rcdev); 296 u32 domain = FIELD_GET(ID_DOMAIN_MASK, id); 297 u32 offset = FIELD_GET(ID_OFFSET_MASK, id); 298 299 dev_dbg(rcdev->dev, "%u-%u: assert request\n", domain, offset); 300 301 guard(mutex)(&priv->mutexes[domain]); 302 303 eqr_assert_locked(priv, domain, offset); 304 return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, true); 305 } 306 307 static void eqr_deassert_locked(struct eqr_private *priv, u32 domain, 308 u32 offset) 309 { 310 enum eqr_domain_type domain_type = priv->data->domains[domain].type; 311 void __iomem *base, *reg; 312 u32 val; 313 314 lockdep_assert_held(&priv->mutexes[domain]); 315 316 base = priv->base + priv->data->domains[domain].offset; 317 318 switch (domain_type) { 319 case EQR_EYEQ5_SARCR: 320 reg = base + EQR_EYEQ5_SARCR_REQUEST; 321 writel(readl(reg) | BIT(offset), reg); 322 break; 323 324 case EQR_EYEQ5_ACRP: 325 reg = base + 4 * offset; 326 writel(readl(reg) & ~EQR_EYEQ5_ACRP_PD_REQ, reg); 327 break; 328 329 case EQR_EYEQ5_PCIE: 330 writel(readl(base) | BIT(offset), base); 331 break; 332 333 case EQR_EYEQ6H_SARCR: 334 /* RST_REQUEST and CLK_REQUEST must be kept in sync. */ 335 val = readl(base + EQR_EYEQ6H_SARCR_RST_REQUEST); 336 val |= BIT(offset); 337 writel(val, base + EQR_EYEQ6H_SARCR_RST_REQUEST); 338 writel(val, base + EQR_EYEQ6H_SARCR_CLK_REQUEST); 339 break; 340 341 default: 342 WARN_ON(1); 343 break; 344 } 345 } 346 347 static int eqr_deassert(struct reset_controller_dev *rcdev, unsigned long id) 348 { 349 struct eqr_private *priv = eqr_rcdev_to_priv(rcdev); 350 u32 domain = FIELD_GET(ID_DOMAIN_MASK, id); 351 u32 offset = FIELD_GET(ID_OFFSET_MASK, id); 352 353 dev_dbg(rcdev->dev, "%u-%u: deassert request\n", domain, offset); 354 355 guard(mutex)(&priv->mutexes[domain]); 356 357 eqr_deassert_locked(priv, domain, offset); 358 return eqr_busy_wait_locked(priv, rcdev->dev, domain, offset, false); 359 } 360 361 static int eqr_status(struct reset_controller_dev *rcdev, unsigned long id) 362 { 363 u32 domain = FIELD_GET(ID_DOMAIN_MASK, id); 364 u32 offset = FIELD_GET(ID_OFFSET_MASK, id); 365 struct eqr_private *priv = eqr_rcdev_to_priv(rcdev); 366 enum eqr_domain_type domain_type = priv->data->domains[domain].type; 367 void __iomem *base, *reg; 368 369 dev_dbg(rcdev->dev, "%u-%u: status request\n", domain, offset); 370 371 guard(mutex)(&priv->mutexes[domain]); 372 373 base = priv->base + priv->data->domains[domain].offset; 374 375 switch (domain_type) { 376 case EQR_EYEQ5_SARCR: 377 reg = base + EQR_EYEQ5_SARCR_STATUS; 378 return !(readl(reg) & BIT(offset)); 379 case EQR_EYEQ5_ACRP: 380 reg = base + 4 * offset; 381 return !(readl(reg) & EQR_EYEQ5_ACRP_ST_ACTIVE); 382 case EQR_EYEQ5_PCIE: 383 return !(readl(base) & BIT(offset)); 384 case EQR_EYEQ6H_SARCR: 385 reg = base + EQR_EYEQ6H_SARCR_RST_STATUS; 386 return !(readl(reg) & BIT(offset)); 387 default: 388 return -EINVAL; 389 } 390 } 391 392 static const struct reset_control_ops eqr_ops = { 393 .assert = eqr_assert, 394 .deassert = eqr_deassert, 395 .status = eqr_status, 396 }; 397 398 static int eqr_of_xlate_internal(struct reset_controller_dev *rcdev, 399 u32 domain, u32 offset) 400 { 401 struct eqr_private *priv = eqr_rcdev_to_priv(rcdev); 402 403 if (domain >= priv->data->domain_count || offset > 31 || 404 !(priv->data->domains[domain].valid_mask & BIT(offset))) { 405 dev_err(rcdev->dev, "%u-%u: invalid reset\n", domain, offset); 406 return -EINVAL; 407 } 408 409 return FIELD_PREP(ID_DOMAIN_MASK, domain) | FIELD_PREP(ID_OFFSET_MASK, offset); 410 } 411 412 static int eqr_of_xlate_onecell(struct reset_controller_dev *rcdev, 413 const struct of_phandle_args *reset_spec) 414 { 415 return eqr_of_xlate_internal(rcdev, 0, reset_spec->args[0]); 416 } 417 418 static int eqr_of_xlate_twocells(struct reset_controller_dev *rcdev, 419 const struct of_phandle_args *reset_spec) 420 { 421 return eqr_of_xlate_internal(rcdev, reset_spec->args[0], reset_spec->args[1]); 422 } 423 424 static int eqr_probe(struct auxiliary_device *adev, 425 const struct auxiliary_device_id *id) 426 { 427 const struct of_device_id *match; 428 struct device *dev = &adev->dev; 429 struct eqr_private *priv; 430 unsigned int i; 431 int ret; 432 433 /* 434 * Get match data. We cannot use device_get_match_data() because it does 435 * not accept reused OF nodes; see device_set_of_node_from_dev(). 436 */ 437 match = of_match_node(dev->driver->of_match_table, dev->of_node); 438 if (!match || !match->data) 439 return -ENODEV; 440 441 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 442 if (!priv) 443 return -ENOMEM; 444 445 priv->data = match->data; 446 priv->base = (void __iomem *)dev_get_platdata(dev); 447 priv->rcdev.ops = &eqr_ops; 448 priv->rcdev.owner = THIS_MODULE; 449 priv->rcdev.dev = dev; 450 priv->rcdev.of_node = dev->of_node; 451 452 if (priv->data->domain_count == 1) { 453 priv->rcdev.of_reset_n_cells = 1; 454 priv->rcdev.of_xlate = eqr_of_xlate_onecell; 455 } else { 456 priv->rcdev.of_reset_n_cells = 2; 457 priv->rcdev.of_xlate = eqr_of_xlate_twocells; 458 } 459 460 for (i = 0; i < priv->data->domain_count; i++) 461 mutex_init(&priv->mutexes[i]); 462 463 priv->rcdev.nr_resets = 0; 464 for (i = 0; i < priv->data->domain_count; i++) 465 priv->rcdev.nr_resets += hweight32(priv->data->domains[i].valid_mask); 466 467 ret = devm_reset_controller_register(dev, &priv->rcdev); 468 if (ret) 469 return dev_err_probe(dev, ret, "failed registering reset controller\n"); 470 471 return 0; 472 } 473 474 static const struct eqr_domain_descriptor eqr_eyeq5_domains[] = { 475 { 476 .type = EQR_EYEQ5_SARCR, 477 .valid_mask = 0xFFFFFF8, 478 .offset = 0x004, 479 }, 480 { 481 .type = EQR_EYEQ5_ACRP, 482 .valid_mask = 0x0001FFF, 483 .offset = 0x200, 484 }, 485 { 486 .type = EQR_EYEQ5_PCIE, 487 .valid_mask = 0x007BFFF, 488 .offset = 0x120, 489 }, 490 }; 491 492 static const struct eqr_match_data eqr_eyeq5_data = { 493 .domain_count = ARRAY_SIZE(eqr_eyeq5_domains), 494 .domains = eqr_eyeq5_domains, 495 }; 496 497 static const struct eqr_domain_descriptor eqr_eyeq6l_domains[] = { 498 { 499 .type = EQR_EYEQ5_SARCR, 500 .valid_mask = 0x3FFF, 501 .offset = 0x004, 502 }, 503 { 504 .type = EQR_EYEQ5_ACRP, 505 .valid_mask = 0x00FF, 506 .offset = 0x200, 507 }, 508 }; 509 510 static const struct eqr_match_data eqr_eyeq6l_data = { 511 .domain_count = ARRAY_SIZE(eqr_eyeq6l_domains), 512 .domains = eqr_eyeq6l_domains, 513 }; 514 515 static const struct eqr_domain_descriptor eqr_eyeq6lplus_domains[] = { 516 { 517 .type = EQR_EYEQ5_PCIE, 518 .valid_mask = 0x3FFF, 519 .offset = 0x004, 520 }, 521 { 522 .type = EQR_EYEQ5_ACRP, 523 .valid_mask = 0x00FF, 524 .offset = 0x200, 525 }, 526 }; 527 528 static const struct eqr_match_data eqr_eyeq6lplus_data = { 529 .domain_count = ARRAY_SIZE(eqr_eyeq6lplus_domains), 530 .domains = eqr_eyeq6lplus_domains, 531 }; 532 533 /* West and east OLBs each have an instance. */ 534 static const struct eqr_domain_descriptor eqr_eyeq6h_we_domains[] = { 535 { 536 .type = EQR_EYEQ6H_SARCR, 537 .valid_mask = 0x1F7F, 538 .offset = 0x004, 539 }, 540 }; 541 542 static const struct eqr_match_data eqr_eyeq6h_we_data = { 543 .domain_count = ARRAY_SIZE(eqr_eyeq6h_we_domains), 544 .domains = eqr_eyeq6h_we_domains, 545 }; 546 547 static const struct eqr_domain_descriptor eqr_eyeq6h_acc_domains[] = { 548 { 549 .type = EQR_EYEQ5_ACRP, 550 .valid_mask = 0x7FFF, 551 .offset = 0x000, 552 }, 553 }; 554 555 static const struct eqr_match_data eqr_eyeq6h_acc_data = { 556 .domain_count = ARRAY_SIZE(eqr_eyeq6h_acc_domains), 557 .domains = eqr_eyeq6h_acc_domains, 558 }; 559 560 /* 561 * Table describes OLB system-controller compatibles. 562 * It does not get used to match against devicetree node. 563 */ 564 static const struct of_device_id eqr_match_table[] = { 565 { .compatible = "mobileye,eyeq5-olb", .data = &eqr_eyeq5_data }, 566 { .compatible = "mobileye,eyeq6l-olb", .data = &eqr_eyeq6l_data }, 567 { .compatible = "mobileye,eyeq6lplus-olb", .data = &eqr_eyeq6lplus_data }, 568 { .compatible = "mobileye,eyeq6h-west-olb", .data = &eqr_eyeq6h_we_data }, 569 { .compatible = "mobileye,eyeq6h-east-olb", .data = &eqr_eyeq6h_we_data }, 570 { .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqr_eyeq6h_acc_data }, 571 {} 572 }; 573 MODULE_DEVICE_TABLE(of, eqr_match_table); 574 575 static const struct auxiliary_device_id eqr_id_table[] = { 576 { .name = "clk_eyeq.reset" }, 577 { .name = "clk_eyeq.reset_west" }, 578 { .name = "clk_eyeq.reset_east" }, 579 { .name = "clk_eyeq.reset_acc" }, 580 {} 581 }; 582 MODULE_DEVICE_TABLE(auxiliary, eqr_id_table); 583 584 static struct auxiliary_driver eqr_driver = { 585 .probe = eqr_probe, 586 .id_table = eqr_id_table, 587 .driver = { 588 .of_match_table = eqr_match_table, 589 } 590 }; 591 module_auxiliary_driver(eqr_driver); 592