1 // SPDX-License-Identifier: GPL-2.0-or-later 2 // Copyright (C) IBM Corporation 2018 3 // FSI master driver for AST2600 4 5 #include <linux/clk.h> 6 #include <linux/delay.h> 7 #include <linux/fsi.h> 8 #include <linux/io.h> 9 #include <linux/mfd/syscon.h> 10 #include <linux/module.h> 11 #include <linux/mutex.h> 12 #include <linux/of.h> 13 #include <linux/platform_device.h> 14 #include <linux/regmap.h> 15 #include <linux/slab.h> 16 #include <linux/iopoll.h> 17 #include <linux/gpio/consumer.h> 18 19 #include "fsi-master.h" 20 21 struct fsi_master_aspeed { 22 struct fsi_master master; 23 struct mutex lock; /* protect HW access */ 24 struct device *dev; 25 void __iomem *base; 26 struct clk *clk; 27 struct gpio_desc *cfam_reset_gpio; 28 }; 29 30 #define to_fsi_master_aspeed(m) \ 31 container_of(m, struct fsi_master_aspeed, master) 32 33 /* Control register (size 0x400) */ 34 static const u32 ctrl_base = 0x80000000; 35 36 static const u32 fsi_base = 0xa0000000; 37 38 #define OPB_FSI_VER 0x00 39 #define OPB_TRIGGER 0x04 40 #define OPB_CTRL_BASE 0x08 41 #define OPB_FSI_BASE 0x0c 42 #define OPB_CLK_SYNC 0x3c 43 #define OPB_IRQ_CLEAR 0x40 44 #define OPB_IRQ_MASK 0x44 45 #define OPB_IRQ_STATUS 0x48 46 47 #define OPB0_SELECT 0x10 48 #define OPB0_RW 0x14 49 #define OPB0_XFER_SIZE 0x18 50 #define OPB0_FSI_ADDR 0x1c 51 #define OPB0_FSI_DATA_W 0x20 52 #define OPB0_STATUS 0x80 53 #define OPB0_FSI_DATA_R 0x84 54 55 #define OPB0_WRITE_ORDER1 0x4c 56 #define OPB0_WRITE_ORDER2 0x50 57 #define OPB1_WRITE_ORDER1 0x54 58 #define OPB1_WRITE_ORDER2 0x58 59 #define OPB0_READ_ORDER1 0x5c 60 #define OPB1_READ_ORDER2 0x60 61 62 #define OPB_RETRY_COUNTER 0x64 63 64 /* OPBn_STATUS */ 65 #define STATUS_HALFWORD_ACK BIT(0) 66 #define STATUS_FULLWORD_ACK BIT(1) 67 #define STATUS_ERR_ACK BIT(2) 68 #define STATUS_RETRY BIT(3) 69 #define STATUS_TIMEOUT BIT(4) 70 71 /* OPB_IRQ_MASK */ 72 #define OPB1_XFER_ACK_EN BIT(17) 73 #define OPB0_XFER_ACK_EN BIT(16) 74 75 /* OPB_RW */ 76 #define CMD_READ BIT(0) 77 #define CMD_WRITE 0 78 79 /* OPBx_XFER_SIZE */ 80 #define XFER_FULLWORD (BIT(1) | BIT(0)) 81 #define XFER_HALFWORD (BIT(0)) 82 #define XFER_BYTE (0) 83 84 #define CREATE_TRACE_POINTS 85 #include <trace/events/fsi_master_aspeed.h> 86 87 #define FSI_LINK_ENABLE_SETUP_TIME 10 /* in mS */ 88 89 /* Run the bus at maximum speed by default */ 90 #define FSI_DIVISOR_DEFAULT 1 91 #define FSI_DIVISOR_CABLED 2 92 static u16 aspeed_fsi_divisor = FSI_DIVISOR_DEFAULT; 93 module_param_named(bus_div,aspeed_fsi_divisor, ushort, 0); 94 95 #define OPB_POLL_TIMEOUT 500 96 97 static int __opb_write(struct fsi_master_aspeed *aspeed, u32 addr, 98 u32 val, u32 transfer_size) 99 { 100 void __iomem *base = aspeed->base; 101 u32 reg, status; 102 int ret; 103 104 /* 105 * The ordering of these writes up until the trigger 106 * write does not matter, so use writel_relaxed. 107 */ 108 writel_relaxed(CMD_WRITE, base + OPB0_RW); 109 writel_relaxed(transfer_size, base + OPB0_XFER_SIZE); 110 writel_relaxed(addr, base + OPB0_FSI_ADDR); 111 writel_relaxed(val, base + OPB0_FSI_DATA_W); 112 writel_relaxed(0x1, base + OPB_IRQ_CLEAR); 113 writel(0x1, base + OPB_TRIGGER); 114 115 ret = readl_poll_timeout(base + OPB_IRQ_STATUS, reg, 116 (reg & OPB0_XFER_ACK_EN) != 0, 117 0, OPB_POLL_TIMEOUT); 118 119 status = readl(base + OPB0_STATUS); 120 121 trace_fsi_master_aspeed_opb_write(addr, val, transfer_size, status, reg); 122 123 /* Return error when poll timed out */ 124 if (ret) 125 return ret; 126 127 /* Command failed, master will reset */ 128 if (status & STATUS_ERR_ACK) 129 return -EIO; 130 131 return 0; 132 } 133 134 static int opb_writeb(struct fsi_master_aspeed *aspeed, u32 addr, u8 val) 135 { 136 return __opb_write(aspeed, addr, val, XFER_BYTE); 137 } 138 139 static int opb_writew(struct fsi_master_aspeed *aspeed, u32 addr, __be16 val) 140 { 141 return __opb_write(aspeed, addr, (__force u16)val, XFER_HALFWORD); 142 } 143 144 static int opb_writel(struct fsi_master_aspeed *aspeed, u32 addr, __be32 val) 145 { 146 return __opb_write(aspeed, addr, (__force u32)val, XFER_FULLWORD); 147 } 148 149 static int __opb_read(struct fsi_master_aspeed *aspeed, uint32_t addr, 150 u32 transfer_size, void *out) 151 { 152 void __iomem *base = aspeed->base; 153 u32 result, reg; 154 int status, ret; 155 156 /* 157 * The ordering of these writes up until the trigger 158 * write does not matter, so use writel_relaxed. 159 */ 160 writel_relaxed(CMD_READ, base + OPB0_RW); 161 writel_relaxed(transfer_size, base + OPB0_XFER_SIZE); 162 writel_relaxed(addr, base + OPB0_FSI_ADDR); 163 writel_relaxed(0x1, base + OPB_IRQ_CLEAR); 164 writel(0x1, base + OPB_TRIGGER); 165 166 ret = readl_poll_timeout(base + OPB_IRQ_STATUS, reg, 167 (reg & OPB0_XFER_ACK_EN) != 0, 168 0, OPB_POLL_TIMEOUT); 169 170 status = readl(base + OPB0_STATUS); 171 172 result = readl(base + OPB0_FSI_DATA_R); 173 174 trace_fsi_master_aspeed_opb_read(addr, transfer_size, result, 175 readl(base + OPB0_STATUS), 176 reg); 177 178 /* Return error when poll timed out */ 179 if (ret) 180 return ret; 181 182 /* Command failed, master will reset */ 183 if (status & STATUS_ERR_ACK) 184 return -EIO; 185 186 if (out) { 187 switch (transfer_size) { 188 case XFER_BYTE: 189 *(u8 *)out = result; 190 break; 191 case XFER_HALFWORD: 192 *(u16 *)out = result; 193 break; 194 case XFER_FULLWORD: 195 *(u32 *)out = result; 196 break; 197 default: 198 return -EINVAL; 199 } 200 201 } 202 203 return 0; 204 } 205 206 static int opb_readl(struct fsi_master_aspeed *aspeed, uint32_t addr, __be32 *out) 207 { 208 return __opb_read(aspeed, addr, XFER_FULLWORD, out); 209 } 210 211 static int opb_readw(struct fsi_master_aspeed *aspeed, uint32_t addr, __be16 *out) 212 { 213 return __opb_read(aspeed, addr, XFER_HALFWORD, (void *)out); 214 } 215 216 static int opb_readb(struct fsi_master_aspeed *aspeed, uint32_t addr, u8 *out) 217 { 218 return __opb_read(aspeed, addr, XFER_BYTE, (void *)out); 219 } 220 221 static int check_errors(struct fsi_master_aspeed *aspeed, int err) 222 { 223 int ret; 224 225 if (trace_fsi_master_aspeed_opb_error_enabled()) { 226 __be32 mresp0, mstap0, mesrb0; 227 228 opb_readl(aspeed, ctrl_base + FSI_MRESP0, &mresp0); 229 opb_readl(aspeed, ctrl_base + FSI_MSTAP0, &mstap0); 230 opb_readl(aspeed, ctrl_base + FSI_MESRB0, &mesrb0); 231 232 trace_fsi_master_aspeed_opb_error( 233 be32_to_cpu(mresp0), 234 be32_to_cpu(mstap0), 235 be32_to_cpu(mesrb0)); 236 } 237 238 if (err == -EIO) { 239 /* Check MAEB (0x70) ? */ 240 241 /* Then clear errors in master */ 242 ret = opb_writel(aspeed, ctrl_base + FSI_MRESP0, 243 cpu_to_be32(FSI_MRESP_RST_ALL_MASTER)); 244 if (ret) { 245 /* TODO: log? return different code? */ 246 return ret; 247 } 248 /* TODO: confirm that 0x70 was okay */ 249 } 250 251 /* This will pass through timeout errors */ 252 return err; 253 } 254 255 static int aspeed_master_read(struct fsi_master *master, int link, 256 uint8_t id, uint32_t addr, void *val, size_t size) 257 { 258 struct fsi_master_aspeed *aspeed = to_fsi_master_aspeed(master); 259 int ret; 260 261 if (id > 0x3) 262 return -EINVAL; 263 264 addr |= id << 21; 265 addr += link * FSI_HUB_LINK_SIZE; 266 267 mutex_lock(&aspeed->lock); 268 269 switch (size) { 270 case 1: 271 ret = opb_readb(aspeed, fsi_base + addr, val); 272 break; 273 case 2: 274 ret = opb_readw(aspeed, fsi_base + addr, val); 275 break; 276 case 4: 277 ret = opb_readl(aspeed, fsi_base + addr, val); 278 break; 279 default: 280 ret = -EINVAL; 281 goto done; 282 } 283 284 ret = check_errors(aspeed, ret); 285 done: 286 mutex_unlock(&aspeed->lock); 287 return ret; 288 } 289 290 static int aspeed_master_write(struct fsi_master *master, int link, 291 uint8_t id, uint32_t addr, const void *val, size_t size) 292 { 293 struct fsi_master_aspeed *aspeed = to_fsi_master_aspeed(master); 294 int ret; 295 296 if (id > 0x3) 297 return -EINVAL; 298 299 addr |= id << 21; 300 addr += link * FSI_HUB_LINK_SIZE; 301 302 mutex_lock(&aspeed->lock); 303 304 switch (size) { 305 case 1: 306 ret = opb_writeb(aspeed, fsi_base + addr, *(u8 *)val); 307 break; 308 case 2: 309 ret = opb_writew(aspeed, fsi_base + addr, *(__be16 *)val); 310 break; 311 case 4: 312 ret = opb_writel(aspeed, fsi_base + addr, *(__be32 *)val); 313 break; 314 default: 315 ret = -EINVAL; 316 goto done; 317 } 318 319 ret = check_errors(aspeed, ret); 320 done: 321 mutex_unlock(&aspeed->lock); 322 return ret; 323 } 324 325 static int aspeed_master_link_enable(struct fsi_master *master, int link, 326 bool enable) 327 { 328 struct fsi_master_aspeed *aspeed = to_fsi_master_aspeed(master); 329 int idx, bit, ret; 330 __be32 reg; 331 332 idx = link / 32; 333 bit = link % 32; 334 335 reg = cpu_to_be32(0x80000000 >> bit); 336 337 mutex_lock(&aspeed->lock); 338 339 if (!enable) { 340 ret = opb_writel(aspeed, ctrl_base + FSI_MCENP0 + (4 * idx), reg); 341 goto done; 342 } 343 344 ret = opb_writel(aspeed, ctrl_base + FSI_MSENP0 + (4 * idx), reg); 345 if (ret) 346 goto done; 347 348 mdelay(FSI_LINK_ENABLE_SETUP_TIME); 349 done: 350 mutex_unlock(&aspeed->lock); 351 return ret; 352 } 353 354 static int aspeed_master_term(struct fsi_master *master, int link, uint8_t id) 355 { 356 uint32_t addr; 357 __be32 cmd; 358 359 addr = 0x4; 360 cmd = cpu_to_be32(0xecc00000); 361 362 return aspeed_master_write(master, link, id, addr, &cmd, 4); 363 } 364 365 static int aspeed_master_break(struct fsi_master *master, int link) 366 { 367 uint32_t addr; 368 __be32 cmd; 369 370 addr = 0x0; 371 cmd = cpu_to_be32(0xc0de0000); 372 373 return aspeed_master_write(master, link, 0, addr, &cmd, 4); 374 } 375 376 static void aspeed_master_release(struct device *dev) 377 { 378 struct fsi_master_aspeed *aspeed = 379 to_fsi_master_aspeed(to_fsi_master(dev)); 380 381 kfree(aspeed); 382 } 383 384 /* mmode encoders */ 385 static inline u32 fsi_mmode_crs0(u32 x) 386 { 387 return (x & FSI_MMODE_CRS0MASK) << FSI_MMODE_CRS0SHFT; 388 } 389 390 static inline u32 fsi_mmode_crs1(u32 x) 391 { 392 return (x & FSI_MMODE_CRS1MASK) << FSI_MMODE_CRS1SHFT; 393 } 394 395 static int aspeed_master_init(struct fsi_master_aspeed *aspeed) 396 { 397 __be32 reg; 398 399 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK 400 | FSI_MRESP_RST_MCR | FSI_MRESP_RST_PYE); 401 opb_writel(aspeed, ctrl_base + FSI_MRESP0, reg); 402 403 /* Initialize the MFSI (hub master) engine */ 404 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK 405 | FSI_MRESP_RST_MCR | FSI_MRESP_RST_PYE); 406 opb_writel(aspeed, ctrl_base + FSI_MRESP0, reg); 407 408 reg = cpu_to_be32(FSI_MECTRL_EOAE | FSI_MECTRL_P8_AUTO_TERM); 409 opb_writel(aspeed, ctrl_base + FSI_MECTRL, reg); 410 411 reg = cpu_to_be32(FSI_MMODE_ECRC | FSI_MMODE_EPC | FSI_MMODE_RELA 412 | fsi_mmode_crs0(aspeed_fsi_divisor) 413 | fsi_mmode_crs1(aspeed_fsi_divisor) 414 | FSI_MMODE_P8_TO_LSB); 415 dev_info(aspeed->dev, "mmode set to %08x (divisor %d)\n", 416 be32_to_cpu(reg), aspeed_fsi_divisor); 417 opb_writel(aspeed, ctrl_base + FSI_MMODE, reg); 418 419 reg = cpu_to_be32(0xffff0000); 420 opb_writel(aspeed, ctrl_base + FSI_MDLYR, reg); 421 422 reg = cpu_to_be32(~0); 423 opb_writel(aspeed, ctrl_base + FSI_MSENP0, reg); 424 425 /* Leave enabled long enough for master logic to set up */ 426 mdelay(FSI_LINK_ENABLE_SETUP_TIME); 427 428 opb_writel(aspeed, ctrl_base + FSI_MCENP0, reg); 429 430 opb_readl(aspeed, ctrl_base + FSI_MAEB, NULL); 431 432 reg = cpu_to_be32(FSI_MRESP_RST_ALL_MASTER | FSI_MRESP_RST_ALL_LINK); 433 opb_writel(aspeed, ctrl_base + FSI_MRESP0, reg); 434 435 opb_readl(aspeed, ctrl_base + FSI_MLEVP0, NULL); 436 437 /* Reset the master bridge */ 438 reg = cpu_to_be32(FSI_MRESB_RST_GEN); 439 opb_writel(aspeed, ctrl_base + FSI_MRESB0, reg); 440 441 reg = cpu_to_be32(FSI_MRESB_RST_ERR); 442 opb_writel(aspeed, ctrl_base + FSI_MRESB0, reg); 443 444 return 0; 445 } 446 447 static ssize_t cfam_reset_store(struct device *dev, struct device_attribute *attr, 448 const char *buf, size_t count) 449 { 450 struct fsi_master_aspeed *aspeed = dev_get_drvdata(dev); 451 452 trace_fsi_master_aspeed_cfam_reset(true); 453 mutex_lock(&aspeed->lock); 454 gpiod_set_value(aspeed->cfam_reset_gpio, 1); 455 usleep_range(900, 1000); 456 gpiod_set_value(aspeed->cfam_reset_gpio, 0); 457 usleep_range(900, 1000); 458 opb_writel(aspeed, ctrl_base + FSI_MRESP0, cpu_to_be32(FSI_MRESP_RST_ALL_MASTER)); 459 mutex_unlock(&aspeed->lock); 460 trace_fsi_master_aspeed_cfam_reset(false); 461 462 return count; 463 } 464 465 static DEVICE_ATTR(cfam_reset, 0200, NULL, cfam_reset_store); 466 467 static int setup_cfam_reset(struct fsi_master_aspeed *aspeed) 468 { 469 struct device *dev = aspeed->dev; 470 struct gpio_desc *gpio; 471 int rc; 472 473 gpio = devm_gpiod_get_optional(dev, "cfam-reset", GPIOD_OUT_LOW); 474 if (IS_ERR(gpio)) 475 return PTR_ERR(gpio); 476 if (!gpio) 477 return 0; 478 479 aspeed->cfam_reset_gpio = gpio; 480 481 rc = device_create_file(dev, &dev_attr_cfam_reset); 482 if (rc) { 483 devm_gpiod_put(dev, gpio); 484 return rc; 485 } 486 487 return 0; 488 } 489 490 static int tacoma_cabled_fsi_fixup(struct device *dev) 491 { 492 struct gpio_desc *routing_gpio, *mux_gpio; 493 int gpio; 494 495 /* 496 * The routing GPIO is a jumper indicating we should mux for the 497 * externally connected FSI cable. 498 */ 499 routing_gpio = devm_gpiod_get_optional(dev, "fsi-routing", 500 GPIOD_IN | GPIOD_FLAGS_BIT_NONEXCLUSIVE); 501 if (IS_ERR(routing_gpio)) 502 return PTR_ERR(routing_gpio); 503 if (!routing_gpio) 504 return 0; 505 506 mux_gpio = devm_gpiod_get_optional(dev, "fsi-mux", GPIOD_ASIS); 507 if (IS_ERR(mux_gpio)) 508 return PTR_ERR(mux_gpio); 509 if (!mux_gpio) 510 return 0; 511 512 gpio = gpiod_get_value(routing_gpio); 513 if (gpio < 0) 514 return gpio; 515 516 /* If the routing GPIO is high we should set the mux to low. */ 517 if (gpio) { 518 /* 519 * Cable signal integrity means we should run the bus 520 * slightly slower. Do not override if a kernel param 521 * has already overridden. 522 */ 523 if (aspeed_fsi_divisor == FSI_DIVISOR_DEFAULT) 524 aspeed_fsi_divisor = FSI_DIVISOR_CABLED; 525 526 gpiod_direction_output(mux_gpio, 0); 527 dev_info(dev, "FSI configured for external cable\n"); 528 } else { 529 gpiod_direction_output(mux_gpio, 1); 530 } 531 532 devm_gpiod_put(dev, routing_gpio); 533 534 return 0; 535 } 536 537 static int fsi_master_aspeed_probe(struct platform_device *pdev) 538 { 539 struct fsi_master_aspeed *aspeed; 540 int rc, links, reg; 541 __be32 raw; 542 543 rc = tacoma_cabled_fsi_fixup(&pdev->dev); 544 if (rc) { 545 dev_err(&pdev->dev, "Tacoma FSI cable fixup failed\n"); 546 return rc; 547 } 548 549 aspeed = kzalloc(sizeof(*aspeed), GFP_KERNEL); 550 if (!aspeed) 551 return -ENOMEM; 552 553 aspeed->dev = &pdev->dev; 554 555 aspeed->base = devm_platform_ioremap_resource(pdev, 0); 556 if (IS_ERR(aspeed->base)) { 557 rc = PTR_ERR(aspeed->base); 558 goto err_free_aspeed; 559 } 560 561 aspeed->clk = devm_clk_get(aspeed->dev, NULL); 562 if (IS_ERR(aspeed->clk)) { 563 dev_err(aspeed->dev, "couldn't get clock\n"); 564 rc = PTR_ERR(aspeed->clk); 565 goto err_free_aspeed; 566 } 567 rc = clk_prepare_enable(aspeed->clk); 568 if (rc) { 569 dev_err(aspeed->dev, "couldn't enable clock\n"); 570 goto err_free_aspeed; 571 } 572 573 rc = setup_cfam_reset(aspeed); 574 if (rc) { 575 dev_err(&pdev->dev, "CFAM reset GPIO setup failed\n"); 576 } 577 578 writel(0x1, aspeed->base + OPB_CLK_SYNC); 579 writel(OPB1_XFER_ACK_EN | OPB0_XFER_ACK_EN, 580 aspeed->base + OPB_IRQ_MASK); 581 582 /* TODO: determine an appropriate value */ 583 writel(0x10, aspeed->base + OPB_RETRY_COUNTER); 584 585 writel(ctrl_base, aspeed->base + OPB_CTRL_BASE); 586 writel(fsi_base, aspeed->base + OPB_FSI_BASE); 587 588 /* Set read data order */ 589 writel(0x00030b1b, aspeed->base + OPB0_READ_ORDER1); 590 591 /* Set write data order */ 592 writel(0x0011101b, aspeed->base + OPB0_WRITE_ORDER1); 593 writel(0x0c330f3f, aspeed->base + OPB0_WRITE_ORDER2); 594 595 /* 596 * Select OPB0 for all operations. 597 * Will need to be reworked when enabling DMA or anything that uses 598 * OPB1. 599 */ 600 writel(0x1, aspeed->base + OPB0_SELECT); 601 602 rc = opb_readl(aspeed, ctrl_base + FSI_MVER, &raw); 603 if (rc) { 604 dev_err(&pdev->dev, "failed to read hub version\n"); 605 goto err_release; 606 } 607 608 reg = be32_to_cpu(raw); 609 links = (reg >> 8) & 0xff; 610 dev_info(&pdev->dev, "hub version %08x (%d links)\n", reg, links); 611 612 aspeed->master.dev.parent = &pdev->dev; 613 aspeed->master.dev.release = aspeed_master_release; 614 aspeed->master.dev.of_node = of_node_get(dev_of_node(&pdev->dev)); 615 616 aspeed->master.n_links = links; 617 aspeed->master.read = aspeed_master_read; 618 aspeed->master.write = aspeed_master_write; 619 aspeed->master.send_break = aspeed_master_break; 620 aspeed->master.term = aspeed_master_term; 621 aspeed->master.link_enable = aspeed_master_link_enable; 622 623 dev_set_drvdata(&pdev->dev, aspeed); 624 625 mutex_init(&aspeed->lock); 626 aspeed_master_init(aspeed); 627 628 rc = fsi_master_register(&aspeed->master); 629 if (rc) 630 goto err_release; 631 632 /* At this point, fsi_master_register performs the device_initialize(), 633 * and holds the sole reference on master.dev. This means the device 634 * will be freed (via ->release) during any subsequent call to 635 * fsi_master_unregister. We add our own reference to it here, so we 636 * can perform cleanup (in _remove()) without it being freed before 637 * we're ready. 638 */ 639 get_device(&aspeed->master.dev); 640 return 0; 641 642 err_release: 643 clk_disable_unprepare(aspeed->clk); 644 err_free_aspeed: 645 kfree(aspeed); 646 return rc; 647 } 648 649 static int fsi_master_aspeed_remove(struct platform_device *pdev) 650 { 651 struct fsi_master_aspeed *aspeed = platform_get_drvdata(pdev); 652 653 fsi_master_unregister(&aspeed->master); 654 clk_disable_unprepare(aspeed->clk); 655 656 return 0; 657 } 658 659 static const struct of_device_id fsi_master_aspeed_match[] = { 660 { .compatible = "aspeed,ast2600-fsi-master" }, 661 { }, 662 }; 663 MODULE_DEVICE_TABLE(of, fsi_master_aspeed_match); 664 665 static struct platform_driver fsi_master_aspeed_driver = { 666 .driver = { 667 .name = "fsi-master-aspeed", 668 .of_match_table = fsi_master_aspeed_match, 669 }, 670 .probe = fsi_master_aspeed_probe, 671 .remove = fsi_master_aspeed_remove, 672 }; 673 674 module_platform_driver(fsi_master_aspeed_driver); 675 MODULE_LICENSE("GPL"); 676