diff options
author | Gerhard Sittig <gsi@denx.de> | 2013-08-23 12:01:44 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2013-08-28 04:48:44 -0400 |
commit | b3bfce2bc205ff4fdb4ec0b048513557cef459cf (patch) | |
tree | 5b006b07d78f10705e78e14911f3791de42cf0c6 /drivers/i2c | |
parent | 498c0146213aa5fbca3b63a6525e91c606c20c5e (diff) |
i2c: mpc: cleanup clock API use
make the MPC I2C driver get, prepare and enable the gated clock item for
register access during probe; disable and unprepare the clock upon
remove(), put is done by the devm approach; hold a reference to the
clock over the period of use
clock lookup is non-fatal in this implementation as not all platforms
may provide clock specs in their device tree, but failure to enable a
clock when specified is considered fatal
Signed-off-by: Gerhard Sittig <gsi@denx.de>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-mpc.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f4060939e959..b80c76888cab 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | 24 | #include <linux/io.h> |
24 | #include <linux/fsl_devices.h> | 25 | #include <linux/fsl_devices.h> |
25 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
@@ -66,6 +67,7 @@ struct mpc_i2c { | |||
66 | #ifdef CONFIG_PM_SLEEP | 67 | #ifdef CONFIG_PM_SLEEP |
67 | u8 fdr, dfsrr; | 68 | u8 fdr, dfsrr; |
68 | #endif | 69 | #endif |
70 | struct clk *clk_per; | ||
69 | }; | 71 | }; |
70 | 72 | ||
71 | struct mpc_i2c_divider { | 73 | struct mpc_i2c_divider { |
@@ -622,6 +624,8 @@ static int fsl_i2c_probe(struct platform_device *op) | |||
622 | int result = 0; | 624 | int result = 0; |
623 | int plen; | 625 | int plen; |
624 | struct resource res; | 626 | struct resource res; |
627 | struct clk *clk; | ||
628 | int err; | ||
625 | 629 | ||
626 | match = of_match_device(mpc_i2c_of_match, &op->dev); | 630 | match = of_match_device(mpc_i2c_of_match, &op->dev); |
627 | if (!match) | 631 | if (!match) |
@@ -652,6 +656,21 @@ static int fsl_i2c_probe(struct platform_device *op) | |||
652 | } | 656 | } |
653 | } | 657 | } |
654 | 658 | ||
659 | /* | ||
660 | * enable clock for the I2C peripheral (non fatal), | ||
661 | * keep a reference upon successful allocation | ||
662 | */ | ||
663 | clk = devm_clk_get(&op->dev, NULL); | ||
664 | if (!IS_ERR(clk)) { | ||
665 | err = clk_prepare_enable(clk); | ||
666 | if (err) { | ||
667 | dev_err(&op->dev, "failed to enable clock\n"); | ||
668 | goto fail_request; | ||
669 | } else { | ||
670 | i2c->clk_per = clk; | ||
671 | } | ||
672 | } | ||
673 | |||
655 | if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) { | 674 | if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) { |
656 | clock = MPC_I2C_CLOCK_PRESERVE; | 675 | clock = MPC_I2C_CLOCK_PRESERVE; |
657 | } else { | 676 | } else { |
@@ -697,6 +716,8 @@ static int fsl_i2c_probe(struct platform_device *op) | |||
697 | return result; | 716 | return result; |
698 | 717 | ||
699 | fail_add: | 718 | fail_add: |
719 | if (i2c->clk_per) | ||
720 | clk_disable_unprepare(i2c->clk_per); | ||
700 | free_irq(i2c->irq, i2c); | 721 | free_irq(i2c->irq, i2c); |
701 | fail_request: | 722 | fail_request: |
702 | irq_dispose_mapping(i2c->irq); | 723 | irq_dispose_mapping(i2c->irq); |
@@ -712,6 +733,9 @@ static int fsl_i2c_remove(struct platform_device *op) | |||
712 | 733 | ||
713 | i2c_del_adapter(&i2c->adap); | 734 | i2c_del_adapter(&i2c->adap); |
714 | 735 | ||
736 | if (i2c->clk_per) | ||
737 | clk_disable_unprepare(i2c->clk_per); | ||
738 | |||
715 | if (i2c->irq) | 739 | if (i2c->irq) |
716 | free_irq(i2c->irq, i2c); | 740 | free_irq(i2c->irq, i2c); |
717 | 741 | ||