aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/irda/pxaficp_ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/irda/pxaficp_ir.c')
-rw-r--r--drivers/net/irda/pxaficp_ir.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 55ff0fbe525a..8c09344f58dc 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -23,6 +23,7 @@
23#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/clk.h>
26 27
27#include <net/irda/irda.h> 28#include <net/irda/irda.h>
28#include <net/irda/irmod.h> 29#include <net/irda/irmod.h>
@@ -87,8 +88,30 @@ struct pxa_irda {
87 88
88 struct device *dev; 89 struct device *dev;
89 struct pxaficp_platform_data *pdata; 90 struct pxaficp_platform_data *pdata;
91 struct clk *fir_clk;
92 struct clk *sir_clk;
93 struct clk *cur_clk;
90}; 94};
91 95
96static inline void pxa_irda_disable_clk(struct pxa_irda *si)
97{
98 if (si->cur_clk)
99 clk_disable(si->cur_clk);
100 si->cur_clk = NULL;
101}
102
103static inline void pxa_irda_enable_firclk(struct pxa_irda *si)
104{
105 si->cur_clk = si->fir_clk;
106 clk_enable(si->fir_clk);
107}
108
109static inline void pxa_irda_enable_sirclk(struct pxa_irda *si)
110{
111 si->cur_clk = si->sir_clk;
112 clk_enable(si->sir_clk);
113}
114
92 115
93#define IS_FIR(si) ((si)->speed >= 4000000) 116#define IS_FIR(si) ((si)->speed >= 4000000)
94#define IRDA_FRAME_SIZE_LIMIT 2047 117#define IRDA_FRAME_SIZE_LIMIT 2047
@@ -134,7 +157,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
134 DCSR(si->rxdma) &= ~DCSR_RUN; 157 DCSR(si->rxdma) &= ~DCSR_RUN;
135 /* disable FICP */ 158 /* disable FICP */
136 ICCR0 = 0; 159 ICCR0 = 0;
137 pxa_set_cken(CKEN_FICP, 0); 160 pxa_irda_disable_clk(si);
138 161
139 /* set board transceiver to SIR mode */ 162 /* set board transceiver to SIR mode */
140 si->pdata->transceiver_mode(si->dev, IR_SIRMODE); 163 si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
@@ -144,7 +167,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
144 pxa_gpio_mode(GPIO47_STTXD_MD); 167 pxa_gpio_mode(GPIO47_STTXD_MD);
145 168
146 /* enable the STUART clock */ 169 /* enable the STUART clock */
147 pxa_set_cken(CKEN_STUART, 1); 170 pxa_irda_enable_sirclk(si);
148 } 171 }
149 172
150 /* disable STUART first */ 173 /* disable STUART first */
@@ -169,7 +192,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
169 /* disable STUART */ 192 /* disable STUART */
170 STIER = 0; 193 STIER = 0;
171 STISR = 0; 194 STISR = 0;
172 pxa_set_cken(CKEN_STUART, 0); 195 pxa_irda_disable_clk(si);
173 196
174 /* disable FICP first */ 197 /* disable FICP first */
175 ICCR0 = 0; 198 ICCR0 = 0;
@@ -182,7 +205,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
182 pxa_gpio_mode(GPIO47_ICPTXD_MD); 205 pxa_gpio_mode(GPIO47_ICPTXD_MD);
183 206
184 /* enable the FICP clock */ 207 /* enable the FICP clock */
185 pxa_set_cken(CKEN_FICP, 1); 208 pxa_irda_enable_firclk(si);
186 209
187 si->speed = speed; 210 si->speed = speed;
188 pxa_irda_fir_dma_rx_start(si); 211 pxa_irda_fir_dma_rx_start(si);
@@ -592,16 +615,15 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
592 STIER = 0; 615 STIER = 0;
593 /* disable STUART SIR mode */ 616 /* disable STUART SIR mode */
594 STISR = 0; 617 STISR = 0;
595 /* disable the STUART clock */
596 pxa_set_cken(CKEN_STUART, 0);
597 618
598 /* disable DMA */ 619 /* disable DMA */
599 DCSR(si->txdma) &= ~DCSR_RUN; 620 DCSR(si->txdma) &= ~DCSR_RUN;
600 DCSR(si->rxdma) &= ~DCSR_RUN; 621 DCSR(si->rxdma) &= ~DCSR_RUN;
601 /* disable FICP */ 622 /* disable FICP */
602 ICCR0 = 0; 623 ICCR0 = 0;
603 /* disable the FICP clock */ 624
604 pxa_set_cken(CKEN_FICP, 0); 625 /* disable the STUART or FICP clocks */
626 pxa_irda_disable_clk(si);
605 627
606 DRCMR17 = 0; 628 DRCMR17 = 0;
607 DRCMR18 = 0; 629 DRCMR18 = 0;
@@ -792,6 +814,13 @@ static int pxa_irda_probe(struct platform_device *pdev)
792 si->dev = &pdev->dev; 814 si->dev = &pdev->dev;
793 si->pdata = pdev->dev.platform_data; 815 si->pdata = pdev->dev.platform_data;
794 816
817 si->sir_clk = clk_get(&pdev->dev, "UARTCLK");
818 si->fir_clk = clk_get(&pdev->dev, "FICPCLK");
819 if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) {
820 err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk);
821 goto err_mem_4;
822 }
823
795 /* 824 /*
796 * Initialise the SIR buffers 825 * Initialise the SIR buffers
797 */ 826 */
@@ -831,6 +860,10 @@ static int pxa_irda_probe(struct platform_device *pdev)
831err_mem_5: 860err_mem_5:
832 kfree(si->rx_buff.head); 861 kfree(si->rx_buff.head);
833err_mem_4: 862err_mem_4:
863 if (si->sir_clk && !IS_ERR(si->sir_clk))
864 clk_put(si->sir_clk);
865 if (si->fir_clk && !IS_ERR(si->fir_clk))
866 clk_put(si->fir_clk);
834 free_netdev(dev); 867 free_netdev(dev);
835err_mem_3: 868err_mem_3:
836 release_mem_region(__PREG(FICP), 0x1c); 869 release_mem_region(__PREG(FICP), 0x1c);
@@ -850,6 +883,8 @@ static int pxa_irda_remove(struct platform_device *_dev)
850 unregister_netdev(dev); 883 unregister_netdev(dev);
851 kfree(si->tx_buff.head); 884 kfree(si->tx_buff.head);
852 kfree(si->rx_buff.head); 885 kfree(si->rx_buff.head);
886 clk_put(si->fir_clk);
887 clk_put(si->sir_clk);
853 free_netdev(dev); 888 free_netdev(dev);
854 } 889 }
855 890