1/* 2 * Freescale/Motorola Coldfire Queued SPI driver 3 * 4 * Copyright 2010 Steven King <sfking@fdwdc.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA 19 * 20*/ 21 22#include <linux/kernel.h> 23#include <linux/module.h> 24#include <linux/interrupt.h> 25#include <linux/errno.h> 26#include <linux/platform_device.h> 27#include <linux/sched.h> 28#include <linux/workqueue.h> 29#include <linux/delay.h> 30#include <linux/io.h> 31#include <linux/clk.h> 32#include <linux/err.h> 33#include <linux/spi/spi.h> 34 35#include <asm/coldfire.h> 36#include <asm/mcfqspi.h> 37 38#define DRIVER_NAME "mcfqspi" 39 40#define MCFQSPI_BUSCLK (MCF_BUSCLK / 2) 41 42#define MCFQSPI_QMR 0x00 43#define MCFQSPI_QMR_MSTR 0x8000 44#define MCFQSPI_QMR_CPOL 0x0200 45#define MCFQSPI_QMR_CPHA 0x0100 46#define MCFQSPI_QDLYR 0x04 47#define MCFQSPI_QDLYR_SPE 0x8000 48#define MCFQSPI_QWR 0x08 49#define MCFQSPI_QWR_HALT 0x8000 50#define MCFQSPI_QWR_WREN 0x4000 51#define MCFQSPI_QWR_CSIV 0x1000 52#define MCFQSPI_QIR 0x0C 53#define MCFQSPI_QIR_WCEFB 0x8000 54#define MCFQSPI_QIR_ABRTB 0x4000 55#define MCFQSPI_QIR_ABRTL 0x1000 56#define MCFQSPI_QIR_WCEFE 0x0800 57#define MCFQSPI_QIR_ABRTE 0x0400 58#define MCFQSPI_QIR_SPIFE 0x0100 59#define MCFQSPI_QIR_WCEF 0x0008 60#define MCFQSPI_QIR_ABRT 0x0004 61#define MCFQSPI_QIR_SPIF 0x0001 62#define MCFQSPI_QAR 0x010 63#define MCFQSPI_QAR_TXBUF 0x00 64#define MCFQSPI_QAR_RXBUF 0x10 65#define MCFQSPI_QAR_CMDBUF 0x20 66#define MCFQSPI_QDR 0x014 67#define MCFQSPI_QCR 0x014 68#define MCFQSPI_QCR_CONT 0x8000 69#define MCFQSPI_QCR_BITSE 0x4000 70#define MCFQSPI_QCR_DT 0x2000 71 72struct mcfqspi { 73 void __iomem *iobase; 74 int irq; 75 struct clk *clk; 76 struct mcfqspi_cs_control *cs_control; 77 78 wait_queue_head_t waitq; 79 80 struct work_struct work; 81 struct workqueue_struct *workq; 82 spinlock_t lock; 83 struct list_head msgq; 84}; 85 86static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val) 87{ 88 writew(val, mcfqspi->iobase + MCFQSPI_QMR); 89} 90 91static void mcfqspi_wr_qdlyr(struct mcfqspi *mcfqspi, u16 val) 92{ 93 writew(val, mcfqspi->iobase + MCFQSPI_QDLYR); 94} 95 96static u16 mcfqspi_rd_qdlyr(struct mcfqspi *mcfqspi) 97{ 98 return readw(mcfqspi->iobase + MCFQSPI_QDLYR); 99} 100 101static void mcfqspi_wr_qwr(struct mcfqspi *mcfqspi, u16 val) 102{ 103 writew(val, mcfqspi->iobase + MCFQSPI_QWR); 104} 105 106static void mcfqspi_wr_qir(struct mcfqspi *mcfqspi, u16 val) 107{ 108 writew(val, mcfqspi->iobase + MCFQSPI_QIR); 109} 110 111static void mcfqspi_wr_qar(struct mcfqspi *mcfqspi, u16 val) 112{ 113 writew(val, mcfqspi->iobase + MCFQSPI_QAR); 114} 115 116static void mcfqspi_wr_qdr(struct mcfqspi *mcfqspi, u16 val) 117{ 118 writew(val, mcfqspi->iobase + MCFQSPI_QDR); 119} 120 121static u16 mcfqspi_rd_qdr(struct mcfqspi *mcfqspi) 122{ 123 return readw(mcfqspi->iobase + MCFQSPI_QDR); 124} 125 126static void mcfqspi_cs_select(struct mcfqspi *mcfqspi, u8 chip_select, 127 bool cs_high) 128{ 129 mcfqspi->cs_control->select(mcfqspi->cs_control, chip_select, cs_high); 130} 131 132static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select, 133 bool cs_high) 134{ 135 mcfqspi->cs_control->deselect(mcfqspi->cs_control, chip_select, cs_high); 136} 137 138static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi) 139{ 140 return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ? 141 mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0; 142} 143 144static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi) 145{ 146 if (mcfqspi->cs_control && mcfqspi->cs_control->teardown) 147 mcfqspi->cs_control->teardown(mcfqspi->cs_control); 148} 149 150static u8 mcfqspi_qmr_baud(u32 speed_hz) 151{ 152 return clamp((MCFQSPI_BUSCLK + speed_hz - 1) / speed_hz, 2u, 255u); 153} 154 155static bool mcfqspi_qdlyr_spe(struct mcfqspi *mcfqspi) 156{ 157 return mcfqspi_rd_qdlyr(mcfqspi) & MCFQSPI_QDLYR_SPE; 158} 159 160static irqreturn_t mcfqspi_irq_handler(int this_irq, void *dev_id) 161{ 162 struct mcfqspi *mcfqspi = dev_id; 163 164 /* clear interrupt */ 165 mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE | MCFQSPI_QIR_SPIF); 166 wake_up(&mcfqspi->waitq); 167 168 return IRQ_HANDLED; 169} 170 171static void mcfqspi_transfer_msg8(struct mcfqspi *mcfqspi, unsigned count, 172 const u8 *txbuf, u8 *rxbuf) 173{ 174 unsigned i, n, offset = 0; 175 176 n = min(count, 16u); 177 178 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF); 179 for (i = 0; i < n; ++i) 180 mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE); 181 182 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF); 183 if (txbuf) 184 for (i = 0; i < n; ++i) 185 mcfqspi_wr_qdr(mcfqspi, *txbuf++); 186 else 187 for (i = 0; i < count; ++i) 188 mcfqspi_wr_qdr(mcfqspi, 0); 189 190 count -= n; 191 if (count) { 192 u16 qwr = 0xf08; 193 mcfqspi_wr_qwr(mcfqspi, 0x700); 194 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE); 195 196 do { 197 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi)); 198 mcfqspi_wr_qwr(mcfqspi, qwr); 199 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE); 200 if (rxbuf) { 201 mcfqspi_wr_qar(mcfqspi, 202 MCFQSPI_QAR_RXBUF + offset); 203 for (i = 0; i < 8; ++i) 204 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi); 205 } 206 n = min(count, 8u); 207 if (txbuf) { 208 mcfqspi_wr_qar(mcfqspi, 209 MCFQSPI_QAR_TXBUF + offset); 210 for (i = 0; i < n; ++i) 211 mcfqspi_wr_qdr(mcfqspi, *txbuf++); 212 } 213 qwr = (offset ? 0x808 : 0) + ((n - 1) << 8); 214 offset ^= 8; 215 count -= n; 216 } while (count); 217 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi)); 218 mcfqspi_wr_qwr(mcfqspi, qwr); 219 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE); 220 if (rxbuf) { 221 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset); 222 for (i = 0; i < 8; ++i) 223 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi); 224 offset ^= 8; 225 } 226 } else { 227 mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8); 228 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE); 229 } 230 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi)); 231 if (rxbuf) { 232 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset); 233 for (i = 0; i < n; ++i) 234 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi); 235 } 236} 237 238static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count, 239 const u16 *txbuf, u16 *rxbuf) 240{ 241 unsigned i, n, offset = 0; 242 243 n = min(count, 16u); 244 245 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF); 246 for (i = 0; i < n; ++i) 247 mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE); 248 249 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF); 250 if (txbuf) 251 for (i = 0; i < n; ++i) 252 mcfqspi_wr_qdr(mcfqspi, *txbuf++); 253 else 254 for (i = 0; i < count; ++i) 255 mcfqspi_wr_qdr(mcfqspi, 0); 256 257 count -= n; 258 if (count) { 259 u16 qwr = 0xf08; 260 mcfqspi_wr_qwr(mcfqspi, 0x700); 261 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE); 262 263 do { 264 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi)); 265 mcfqspi_wr_qwr(mcfqspi, qwr); 266 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE); 267 if (rxbuf) { 268 mcfqspi_wr_qar(mcfqspi, 269 MCFQSPI_QAR_RXBUF + offset); 270 for (i = 0; i < 8; ++i) 271 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi); 272 } 273 n = min(count, 8u); 274 if (txbuf) { 275 mcfqspi_wr_qar(mcfqspi, 276 MCFQSPI_QAR_TXBUF + offset); 277 for (i = 0; i < n; ++i) 278 mcfqspi_wr_qdr(mcfqspi, *txbuf++); 279 } 280 qwr = (offset ? 0x808 : 0x000) + ((n - 1) << 8); 281 offset ^= 8; 282 count -= n; 283 } while (count); 284 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi)); 285 mcfqspi_wr_qwr(mcfqspi, qwr); 286 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE); 287 if (rxbuf) { 288 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset); 289 for (i = 0; i < 8; ++i) 290 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi); 291 offset ^= 8; 292 } 293 } else { 294 mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8); 295 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE); 296 } 297 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi)); 298 if (rxbuf) { 299 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset); 300 for (i = 0; i < n; ++i) 301 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi); 302 } 303} 304 305static void mcfqspi_work(struct work_struct *work) 306{ 307 struct mcfqspi *mcfqspi = container_of(work, struct mcfqspi, work); 308 unsigned long flags; 309 310 spin_lock_irqsave(&mcfqspi->lock, flags); 311 while (!list_empty(&mcfqspi->msgq)) { 312 struct spi_message *msg; 313 struct spi_device *spi; 314 struct spi_transfer *xfer; 315 int status = 0; 316 317 msg = container_of(mcfqspi->msgq.next, struct spi_message, 318 queue); 319 320 list_del_init(&mcfqspi->msgq); 321 spin_unlock_irqrestore(&mcfqspi->lock, flags); 322 323 spi = msg->spi; 324 325 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 326 bool cs_high = spi->mode & SPI_CS_HIGH; 327 u16 qmr = MCFQSPI_QMR_MSTR; 328 329 if (xfer->bits_per_word) 330 qmr |= xfer->bits_per_word << 10; 331 else 332 qmr |= spi->bits_per_word << 10; 333 if (spi->mode & SPI_CPHA) 334 qmr |= MCFQSPI_QMR_CPHA; 335 if (spi->mode & SPI_CPOL) 336 qmr |= MCFQSPI_QMR_CPOL; 337 if (xfer->speed_hz) 338 qmr |= mcfqspi_qmr_baud(xfer->speed_hz); 339 else 340 qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); 341 mcfqspi_wr_qmr(mcfqspi, qmr); 342 343 mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); 344 345 mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); 346 if ((xfer->bits_per_word ? xfer->bits_per_word : 347 spi->bits_per_word) == 8) 348 mcfqspi_transfer_msg8(mcfqspi, xfer->len, 349 xfer->tx_buf, 350 xfer->rx_buf); 351 else 352 mcfqspi_transfer_msg16(mcfqspi, xfer->len / 2, 353 xfer->tx_buf, 354 xfer->rx_buf); 355 mcfqspi_wr_qir(mcfqspi, 0); 356 357 if (xfer->delay_usecs) 358 udelay(xfer->delay_usecs); 359 if (xfer->cs_change) { 360 if (!list_is_last(&xfer->transfer_list, 361 &msg->transfers)) 362 mcfqspi_cs_deselect(mcfqspi, 363 spi->chip_select, 364 cs_high); 365 } else { 366 if (list_is_last(&xfer->transfer_list, 367 &msg->transfers)) 368 mcfqspi_cs_deselect(mcfqspi, 369 spi->chip_select, 370 cs_high); 371 } 372 msg->actual_length += xfer->len; 373 } 374 msg->status = status; 375 msg->complete(msg->context); 376 377 spin_lock_irqsave(&mcfqspi->lock, flags); 378 } 379 spin_unlock_irqrestore(&mcfqspi->lock, flags); 380} 381 382static int mcfqspi_transfer(struct spi_device *spi, struct spi_message *msg) 383{ 384 struct mcfqspi *mcfqspi; 385 struct spi_transfer *xfer; 386 unsigned long flags; 387 388 mcfqspi = spi_master_get_devdata(spi->master); 389 390 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 391 if (xfer->bits_per_word && ((xfer->bits_per_word < 8) 392 || (xfer->bits_per_word > 16))) { 393 dev_dbg(&spi->dev, 394 "%d bits per word is not supported\n", 395 xfer->bits_per_word); 396 goto fail; 397 } 398 if (xfer->speed_hz) { 399 u32 real_speed = MCFQSPI_BUSCLK / 400 mcfqspi_qmr_baud(xfer->speed_hz); 401 if (real_speed != xfer->speed_hz) 402 dev_dbg(&spi->dev, 403 "using speed %d instead of %d\n", 404 real_speed, xfer->speed_hz); 405 } 406 } 407 msg->status = -EINPROGRESS; 408 msg->actual_length = 0; 409 410 spin_lock_irqsave(&mcfqspi->lock, flags); 411 list_add_tail(&msg->queue, &mcfqspi->msgq); 412 queue_work(mcfqspi->workq, &mcfqspi->work); 413 spin_unlock_irqrestore(&mcfqspi->lock, flags); 414 415 return 0; 416fail: 417 msg->status = -EINVAL; 418 return -EINVAL; 419} 420 421static int mcfqspi_setup(struct spi_device *spi) 422{ 423 if ((spi->bits_per_word < 8) || (spi->bits_per_word > 16)) { 424 dev_dbg(&spi->dev, "%d bits per word is not supported\n", 425 spi->bits_per_word); 426 return -EINVAL; 427 } 428 if (spi->chip_select >= spi->master->num_chipselect) { 429 dev_dbg(&spi->dev, "%d chip select is out of range\n", 430 spi->chip_select); 431 return -EINVAL; 432 } 433 434 mcfqspi_cs_deselect(spi_master_get_devdata(spi->master), 435 spi->chip_select, spi->mode & SPI_CS_HIGH); 436 437 dev_dbg(&spi->dev, 438 "bits per word %d, chip select %d, speed %d KHz\n", 439 spi->bits_per_word, spi->chip_select, 440 (MCFQSPI_BUSCLK / mcfqspi_qmr_baud(spi->max_speed_hz)) 441 / 1000); 442 443 return 0; 444} 445 446static int __devinit mcfqspi_probe(struct platform_device *pdev) 447{ 448 struct spi_master *master; 449 struct mcfqspi *mcfqspi; 450 struct resource *res; 451 struct mcfqspi_platform_data *pdata; 452 int status; 453 454 master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi)); 455 if (master == NULL) { 456 dev_dbg(&pdev->dev, "spi_alloc_master failed\n"); 457 return -ENOMEM; 458 } 459 460 mcfqspi = spi_master_get_devdata(master); 461 462 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 463 if (!res) { 464 dev_dbg(&pdev->dev, "platform_get_resource failed\n"); 465 status = -ENXIO; 466 goto fail0; 467 } 468 469 if (!request_mem_region(res->start, resource_size(res), pdev->name)) { 470 dev_dbg(&pdev->dev, "request_mem_region failed\n"); 471 status = -EBUSY; 472 goto fail0; 473 } 474 475 mcfqspi->iobase = ioremap(res->start, resource_size(res)); 476 if (!mcfqspi->iobase) { 477 dev_dbg(&pdev->dev, "ioremap failed\n"); 478 status = -ENOMEM; 479 goto fail1; 480 } 481 482 mcfqspi->irq = platform_get_irq(pdev, 0); 483 if (mcfqspi->irq < 0) { 484 dev_dbg(&pdev->dev, "platform_get_irq failed\n"); 485 status = -ENXIO; 486 goto fail2; 487 } 488 489 status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, IRQF_DISABLED, 490 pdev->name, mcfqspi); 491 if (status) { 492 dev_dbg(&pdev->dev, "request_irq failed\n"); 493 goto fail2; 494 } 495 496 mcfqspi->clk = clk_get(&pdev->dev, "qspi_clk"); 497 if (IS_ERR(mcfqspi->clk)) { 498 dev_dbg(&pdev->dev, "clk_get failed\n"); 499 status = PTR_ERR(mcfqspi->clk); 500 goto fail3; 501 } 502 clk_enable(mcfqspi->clk); 503 504 mcfqspi->workq = create_singlethread_workqueue(dev_name(master->dev.parent)); 505 if (!mcfqspi->workq) { 506 dev_dbg(&pdev->dev, "create_workqueue failed\n"); 507 status = -ENOMEM; 508 goto fail4; 509 } 510 INIT_WORK(&mcfqspi->work, mcfqspi_work); 511 spin_lock_init(&mcfqspi->lock); 512 INIT_LIST_HEAD(&mcfqspi->msgq); 513 init_waitqueue_head(&mcfqspi->waitq); 514 515 pdata = pdev->dev.platform_data; 516 if (!pdata) { 517 dev_dbg(&pdev->dev, "platform data is missing\n"); 518 goto fail5; 519 } 520 master->bus_num = pdata->bus_num; 521 master->num_chipselect = pdata->num_chipselect; 522 523 mcfqspi->cs_control = pdata->cs_control; 524 status = mcfqspi_cs_setup(mcfqspi); 525 if (status) { 526 dev_dbg(&pdev->dev, "error initializing cs_control\n"); 527 goto fail5; 528 } 529 530 master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA; 531 master->setup = mcfqspi_setup; 532 master->transfer = mcfqspi_transfer; 533 534 platform_set_drvdata(pdev, master); 535 536 status = spi_register_master(master); 537 if (status) { 538 dev_dbg(&pdev->dev, "spi_register_master failed\n"); 539 goto fail6; 540 } 541 dev_info(&pdev->dev, "Coldfire QSPI bus driver\n"); 542 543 return 0; 544 545fail6: 546 mcfqspi_cs_teardown(mcfqspi); 547fail5: 548 destroy_workqueue(mcfqspi->workq); 549fail4: 550 clk_disable(mcfqspi->clk); 551 clk_put(mcfqspi->clk); 552fail3: 553 free_irq(mcfqspi->irq, mcfqspi); 554fail2: 555 iounmap(mcfqspi->iobase); 556fail1: 557 release_mem_region(res->start, resource_size(res)); 558fail0: 559 spi_master_put(master); 560 561 dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n"); 562 563 return status; 564} 565 566static int __devexit mcfqspi_remove(struct platform_device *pdev) 567{ 568 struct spi_master *master = platform_get_drvdata(pdev); 569 struct mcfqspi *mcfqspi = spi_master_get_devdata(master); 570 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 571 572 /* disable the hardware (set the baud rate to 0) */ 573 mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR); 574 575 platform_set_drvdata(pdev, NULL); 576 mcfqspi_cs_teardown(mcfqspi); 577 destroy_workqueue(mcfqspi->workq); 578 clk_disable(mcfqspi->clk); 579 clk_put(mcfqspi->clk); 580 free_irq(mcfqspi->irq, mcfqspi); 581 iounmap(mcfqspi->iobase); 582 release_mem_region(res->start, resource_size(res)); 583 spi_unregister_master(master); 584 spi_master_put(master); 585 586 return 0; 587} 588 589#ifdef CONFIG_PM 590 591static int mcfqspi_suspend(struct device *dev) 592{ 593 struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev)); 594 595 clk_disable(mcfqspi->clk); 596 597 return 0; 598} 599 600static int mcfqspi_resume(struct device *dev) 601{ 602 struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev)); 603 604 clk_enable(mcfqspi->clk); 605 606 return 0; 607} 608 609static struct dev_pm_ops mcfqspi_dev_pm_ops = { 610 .suspend = mcfqspi_suspend, 611 .resume = mcfqspi_resume, 612}; 613 614#define MCFQSPI_DEV_PM_OPS (&mcfqspi_dev_pm_ops) 615#else 616#define MCFQSPI_DEV_PM_OPS NULL 617#endif 618 619static struct platform_driver mcfqspi_driver = { 620 .driver.name = DRIVER_NAME, 621 .driver.owner = THIS_MODULE, 622 .driver.pm = MCFQSPI_DEV_PM_OPS, 623 .remove = __devexit_p(mcfqspi_remove), 624}; 625 626static int __init mcfqspi_init(void) 627{ 628 return platform_driver_probe(&mcfqspi_driver, mcfqspi_probe); 629} 630module_init(mcfqspi_init); 631 632static void __exit mcfqspi_exit(void) 633{ 634 platform_driver_unregister(&mcfqspi_driver); 635} 636module_exit(mcfqspi_exit); 637 638MODULE_AUTHOR("Steven King <sfking@fdwdc.com>"); 639MODULE_DESCRIPTION("Coldfire QSPI Controller Driver"); 640MODULE_LICENSE("GPL"); 641MODULE_ALIAS("platform:" DRIVER_NAME); 642