diff options
author | Gerhard Sittig <gsi@denx.de> | 2013-08-06 16:43:41 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-08-22 06:02:07 -0400 |
commit | a81a5094a3287120cac148de4c9bdb2e53e5bfae (patch) | |
tree | 110f19076264a98ba13584519810c499fd8942be /drivers/spi/spi-mpc512x-psc.c | |
parent | b36f4be3de1b123d8601de062e7dbfc904f305fb (diff) |
spi: mpc512x: cleanup clock API use
cleanup the MPC512x SoC's SPI master's use of the clock API
- get, prepare, and enable the MCLK during probe; disable, unprepare and
put the MCLK upon remove; hold a reference to the clock over the
period of use
- fetch MCLK rate (reference) once during probe and slightly reword BCLK
(bitrate) determination to reduce redundancy as well as to not exceed
the maximum text line length
- stick with the PPC_CLOCK 'psc%d_mclk' name for clock lookup, only
switch to a fixed string later after device tree based clock lookup
will have become available
Signed-off-by: Gerhard Sittig <gsi@denx.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-mpc512x-psc.c')
-rw-r--r-- | drivers/spi/spi-mpc512x-psc.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 29fce6af5145..85581f307945 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c | |||
@@ -38,7 +38,8 @@ struct mpc512x_psc_spi { | |||
38 | struct mpc512x_psc_fifo __iomem *fifo; | 38 | struct mpc512x_psc_fifo __iomem *fifo; |
39 | unsigned int irq; | 39 | unsigned int irq; |
40 | u8 bits_per_word; | 40 | u8 bits_per_word; |
41 | u32 mclk; | 41 | struct clk *clk_mclk; |
42 | u32 mclk_rate; | ||
42 | 43 | ||
43 | struct completion txisrdone; | 44 | struct completion txisrdone; |
44 | }; | 45 | }; |
@@ -72,6 +73,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) | |||
72 | struct mpc52xx_psc __iomem *psc = mps->psc; | 73 | struct mpc52xx_psc __iomem *psc = mps->psc; |
73 | u32 sicr; | 74 | u32 sicr; |
74 | u32 ccr; | 75 | u32 ccr; |
76 | int speed; | ||
75 | u16 bclkdiv; | 77 | u16 bclkdiv; |
76 | 78 | ||
77 | sicr = in_be32(&psc->sicr); | 79 | sicr = in_be32(&psc->sicr); |
@@ -95,10 +97,10 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) | |||
95 | 97 | ||
96 | ccr = in_be32(&psc->ccr); | 98 | ccr = in_be32(&psc->ccr); |
97 | ccr &= 0xFF000000; | 99 | ccr &= 0xFF000000; |
98 | if (cs->speed_hz) | 100 | speed = cs->speed_hz; |
99 | bclkdiv = (mps->mclk / cs->speed_hz) - 1; | 101 | if (!speed) |
100 | else | 102 | speed = 1000000; /* default 1MHz */ |
101 | bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */ | 103 | bclkdiv = (mps->mclk_rate / speed) - 1; |
102 | 104 | ||
103 | ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); | 105 | ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); |
104 | out_be32(&psc->ccr, ccr); | 106 | out_be32(&psc->ccr, ccr); |
@@ -386,19 +388,11 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, | |||
386 | { | 388 | { |
387 | struct mpc52xx_psc __iomem *psc = mps->psc; | 389 | struct mpc52xx_psc __iomem *psc = mps->psc; |
388 | struct mpc512x_psc_fifo __iomem *fifo = mps->fifo; | 390 | struct mpc512x_psc_fifo __iomem *fifo = mps->fifo; |
389 | struct clk *spiclk; | ||
390 | int ret = 0; | ||
391 | char name[32]; | ||
392 | u32 sicr; | 391 | u32 sicr; |
393 | u32 ccr; | 392 | u32 ccr; |
393 | int speed; | ||
394 | u16 bclkdiv; | 394 | u16 bclkdiv; |
395 | 395 | ||
396 | sprintf(name, "psc%d_mclk", master->bus_num); | ||
397 | spiclk = clk_get(&master->dev, name); | ||
398 | clk_enable(spiclk); | ||
399 | mps->mclk = clk_get_rate(spiclk); | ||
400 | clk_put(spiclk); | ||
401 | |||
402 | /* Reset the PSC into a known state */ | 396 | /* Reset the PSC into a known state */ |
403 | out_8(&psc->command, MPC52xx_PSC_RST_RX); | 397 | out_8(&psc->command, MPC52xx_PSC_RST_RX); |
404 | out_8(&psc->command, MPC52xx_PSC_RST_TX); | 398 | out_8(&psc->command, MPC52xx_PSC_RST_TX); |
@@ -425,7 +419,8 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, | |||
425 | 419 | ||
426 | ccr = in_be32(&psc->ccr); | 420 | ccr = in_be32(&psc->ccr); |
427 | ccr &= 0xFF000000; | 421 | ccr &= 0xFF000000; |
428 | bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */ | 422 | speed = 1000000; /* default 1MHz */ |
423 | bclkdiv = (mps->mclk_rate / speed) - 1; | ||
429 | ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); | 424 | ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); |
430 | out_be32(&psc->ccr, ccr); | 425 | out_be32(&psc->ccr, ccr); |
431 | 426 | ||
@@ -445,7 +440,7 @@ static int mpc512x_psc_spi_port_config(struct spi_master *master, | |||
445 | 440 | ||
446 | mps->bits_per_word = 8; | 441 | mps->bits_per_word = 8; |
447 | 442 | ||
448 | return ret; | 443 | return 0; |
449 | } | 444 | } |
450 | 445 | ||
451 | static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) | 446 | static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) |
@@ -479,6 +474,9 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, | |||
479 | struct spi_master *master; | 474 | struct spi_master *master; |
480 | int ret; | 475 | int ret; |
481 | void *tempp; | 476 | void *tempp; |
477 | int psc_num; | ||
478 | char clk_name[16]; | ||
479 | struct clk *clk; | ||
482 | 480 | ||
483 | master = spi_alloc_master(dev, sizeof *mps); | 481 | master = spi_alloc_master(dev, sizeof *mps); |
484 | if (master == NULL) | 482 | if (master == NULL) |
@@ -521,16 +519,29 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, | |||
521 | goto free_master; | 519 | goto free_master; |
522 | init_completion(&mps->txisrdone); | 520 | init_completion(&mps->txisrdone); |
523 | 521 | ||
522 | psc_num = master->bus_num; | ||
523 | snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); | ||
524 | clk = devm_clk_get(dev, clk_name); | ||
525 | if (IS_ERR(clk)) | ||
526 | goto free_irq; | ||
527 | ret = clk_prepare_enable(clk); | ||
528 | if (ret) | ||
529 | goto free_irq; | ||
530 | mps->clk_mclk = clk; | ||
531 | mps->mclk_rate = clk_get_rate(clk); | ||
532 | |||
524 | ret = mpc512x_psc_spi_port_config(master, mps); | 533 | ret = mpc512x_psc_spi_port_config(master, mps); |
525 | if (ret < 0) | 534 | if (ret < 0) |
526 | goto free_irq; | 535 | goto free_clock; |
527 | 536 | ||
528 | ret = spi_register_master(master); | 537 | ret = spi_register_master(master); |
529 | if (ret < 0) | 538 | if (ret < 0) |
530 | goto free_irq; | 539 | goto free_clock; |
531 | 540 | ||
532 | return ret; | 541 | return ret; |
533 | 542 | ||
543 | free_clock: | ||
544 | clk_disable_unprepare(mps->clk_mclk); | ||
534 | free_irq: | 545 | free_irq: |
535 | free_irq(mps->irq, mps); | 546 | free_irq(mps->irq, mps); |
536 | free_master: | 547 | free_master: |
@@ -547,6 +558,7 @@ static int mpc512x_psc_spi_do_remove(struct device *dev) | |||
547 | struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); | 558 | struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); |
548 | 559 | ||
549 | spi_unregister_master(master); | 560 | spi_unregister_master(master); |
561 | clk_disable_unprepare(mps->clk_mclk); | ||
550 | free_irq(mps->irq, mps); | 562 | free_irq(mps->irq, mps); |
551 | if (mps->psc) | 563 | if (mps->psc) |
552 | iounmap(mps->psc); | 564 | iounmap(mps->psc); |