Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IMX: introduce clock API

This patch introduces the clock API for i.MX and converts all
in-Kernel drivers to use it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

authored by

Sascha Hauer and committed by
Robert Schwebel
38a41fdf dbff4e9e

+308 -110
+1 -1
arch/arm/mach-imx/Makefile
··· 4 4 5 5 # Object file lists. 6 6 7 - obj-y += irq.o time.o dma.o generic.o 7 + obj-y += irq.o time.o dma.o generic.o clock.o 8 8 9 9 obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o 10 10
+205
arch/arm/mach-imx/clock.c
··· 1 + /* 2 + * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 + */ 18 + 19 + #include <linux/kernel.h> 20 + #include <linux/device.h> 21 + #include <linux/list.h> 22 + #include <linux/math64.h> 23 + #include <linux/err.h> 24 + 25 + #include <asm/io.h> 26 + #include <asm/arch/imx-regs.h> 27 + 28 + /* 29 + * Very simple approach: We can't disable clocks, so we do 30 + * not need refcounting 31 + */ 32 + 33 + struct clk { 34 + struct list_head node; 35 + const char *name; 36 + unsigned long (*get_rate)(void); 37 + }; 38 + 39 + /* 40 + * get the system pll clock in Hz 41 + * 42 + * mfi + mfn / (mfd +1) 43 + * f = 2 * f_ref * -------------------- 44 + * pd + 1 45 + */ 46 + static unsigned long imx_decode_pll(unsigned int pll, u32 f_ref) 47 + { 48 + unsigned long long ll; 49 + unsigned long quot; 50 + 51 + u32 mfi = (pll >> 10) & 0xf; 52 + u32 mfn = pll & 0x3ff; 53 + u32 mfd = (pll >> 16) & 0x3ff; 54 + u32 pd = (pll >> 26) & 0xf; 55 + 56 + mfi = mfi <= 5 ? 5 : mfi; 57 + 58 + ll = 2 * (unsigned long long)f_ref * 59 + ((mfi << 16) + (mfn << 16) / (mfd + 1)); 60 + quot = (pd + 1) * (1 << 16); 61 + ll += quot / 2; 62 + do_div(ll, quot); 63 + return (unsigned long)ll; 64 + } 65 + 66 + static unsigned long imx_get_system_clk(void) 67 + { 68 + u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); 69 + 70 + return imx_decode_pll(SPCTL0, f_ref); 71 + } 72 + 73 + static unsigned long imx_get_mcu_clk(void) 74 + { 75 + return imx_decode_pll(MPCTL0, CLK32 * 512); 76 + } 77 + 78 + /* 79 + * get peripheral clock 1 ( UART[12], Timer[12], PWM ) 80 + */ 81 + static unsigned long imx_get_perclk1(void) 82 + { 83 + return imx_get_system_clk() / (((PCDR) & 0xf)+1); 84 + } 85 + 86 + /* 87 + * get peripheral clock 2 ( LCD, SD, SPI[12] ) 88 + */ 89 + static unsigned long imx_get_perclk2(void) 90 + { 91 + return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); 92 + } 93 + 94 + /* 95 + * get peripheral clock 3 ( SSI ) 96 + */ 97 + static unsigned long imx_get_perclk3(void) 98 + { 99 + return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); 100 + } 101 + 102 + /* 103 + * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) 104 + */ 105 + static unsigned long imx_get_hclk(void) 106 + { 107 + return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); 108 + } 109 + 110 + static struct clk clk_system_clk = { 111 + .name = "system_clk", 112 + .get_rate = imx_get_system_clk, 113 + }; 114 + 115 + static struct clk clk_hclk = { 116 + .name = "hclk", 117 + .get_rate = imx_get_hclk, 118 + }; 119 + 120 + static struct clk clk_mcu_clk = { 121 + .name = "mcu_clk", 122 + .get_rate = imx_get_mcu_clk, 123 + }; 124 + 125 + static struct clk clk_perclk1 = { 126 + .name = "perclk1", 127 + .get_rate = imx_get_perclk1, 128 + }; 129 + 130 + static struct clk clk_uart_clk = { 131 + .name = "uart_clk", 132 + .get_rate = imx_get_perclk1, 133 + }; 134 + 135 + static struct clk clk_perclk2 = { 136 + .name = "perclk2", 137 + .get_rate = imx_get_perclk2, 138 + }; 139 + 140 + static struct clk clk_perclk3 = { 141 + .name = "perclk3", 142 + .get_rate = imx_get_perclk3, 143 + }; 144 + 145 + static struct clk *clks[] = { 146 + &clk_perclk1, 147 + &clk_perclk2, 148 + &clk_perclk3, 149 + &clk_system_clk, 150 + &clk_hclk, 151 + &clk_mcu_clk, 152 + &clk_uart_clk, 153 + }; 154 + 155 + static LIST_HEAD(clocks); 156 + static DEFINE_MUTEX(clocks_mutex); 157 + 158 + struct clk *clk_get(struct device *dev, const char *id) 159 + { 160 + struct clk *p, *clk = ERR_PTR(-ENOENT); 161 + 162 + mutex_lock(&clocks_mutex); 163 + list_for_each_entry(p, &clocks, node) { 164 + if (!strcmp(p->name, id)) { 165 + clk = p; 166 + goto found; 167 + } 168 + } 169 + 170 + found: 171 + mutex_unlock(&clocks_mutex); 172 + 173 + return clk; 174 + } 175 + 176 + void clk_put(struct clk *clk) 177 + { 178 + } 179 + 180 + int clk_enable(struct clk *clk) 181 + { 182 + return 0; 183 + } 184 + 185 + void clk_disable(struct clk *clk) 186 + { 187 + } 188 + 189 + unsigned long clk_get_rate(struct clk *clk) 190 + { 191 + return clk->get_rate(); 192 + } 193 + 194 + int imx_clocks_init(void) 195 + { 196 + int i; 197 + 198 + mutex_lock(&clocks_mutex); 199 + for (i = 0; i < ARRAY_SIZE(clks); i++) 200 + list_add(&clks[i]->node, &clocks); 201 + mutex_unlock(&clocks_mutex); 202 + 203 + return 0; 204 + } 205 +
+17 -3
arch/arm/mach-imx/cpufreq.c
··· 32 32 #include <linux/types.h> 33 33 #include <linux/init.h> 34 34 #include <linux/cpufreq.h> 35 + #include <linux/clk.h> 36 + #include <linux/err.h> 35 37 #include <asm/system.h> 36 38 37 39 #include <asm/hardware.h> ··· 53 51 54 52 static u32 mpctl0_at_boot; 55 53 static u32 bclk_div_at_boot; 54 + 55 + static struct clk *system_clk, *mcu_clk; 56 56 57 57 static void imx_set_async_mode(void) 58 58 { ··· 164 160 cr = get_cr(); 165 161 166 162 if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) { 167 - freq = imx_get_system_clk(); 163 + freq = clk_get_rate(system_clk); 168 164 freq = (freq + bclk_div/2) / bclk_div; 169 165 } else { 170 - freq = imx_get_mcu_clk(); 166 + freq = clk_get_rate(mcu_clk); 171 167 if (cscr & CSCR_MPU_PRESC) 172 168 freq /= 2; 173 169 } ··· 205 201 pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n", 206 202 freq, mpctl0_at_boot); 207 203 208 - sysclk = imx_get_system_clk(); 204 + sysclk = clk_get_rate(system_clk); 209 205 210 206 if (freq > sysclk / bclk_div_at_boot + 1000000) { 211 207 freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation); ··· 293 289 { 294 290 bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1; 295 291 mpctl0_at_boot = 0; 292 + 293 + system_clk = clk_get(NULL, "system_clk"); 294 + if (IS_ERR(system_clk)) 295 + return PTR_ERR(system_clk); 296 + 297 + mcu_clk = clk_get(NULL, "mcu_clk"); 298 + if (IS_ERR(mcu_clk)) { 299 + clk_put(system_clk); 300 + return PTR_ERR(mcu_clk); 301 + } 296 302 297 303 if((CSCR & CSCR_MPEN) && 298 304 ((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE))
-76
arch/arm/mach-imx/generic.c
··· 214 214 215 215 EXPORT_SYMBOL(imx_irq_to_gpio); 216 216 217 - /* 218 - * get the system pll clock in Hz 219 - * 220 - * mfi + mfn / (mfd +1) 221 - * f = 2 * f_ref * -------------------- 222 - * pd + 1 223 - */ 224 - static unsigned int imx_decode_pll(unsigned int pll, u32 f_ref) 225 - { 226 - unsigned long long ll; 227 - unsigned long quot; 228 - 229 - u32 mfi = (pll >> 10) & 0xf; 230 - u32 mfn = pll & 0x3ff; 231 - u32 mfd = (pll >> 16) & 0x3ff; 232 - u32 pd = (pll >> 26) & 0xf; 233 - 234 - mfi = mfi <= 5 ? 5 : mfi; 235 - 236 - ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) ); 237 - quot = (pd+1) * (1<<16); 238 - ll += quot / 2; 239 - do_div(ll, quot); 240 - return (unsigned int) ll; 241 - } 242 - 243 - unsigned int imx_get_system_clk(void) 244 - { 245 - u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); 246 - 247 - return imx_decode_pll(SPCTL0, f_ref); 248 - } 249 - EXPORT_SYMBOL(imx_get_system_clk); 250 - 251 - unsigned int imx_get_mcu_clk(void) 252 - { 253 - return imx_decode_pll(MPCTL0, CLK32 * 512); 254 - } 255 - EXPORT_SYMBOL(imx_get_mcu_clk); 256 - 257 - /* 258 - * get peripheral clock 1 ( UART[12], Timer[12], PWM ) 259 - */ 260 - unsigned int imx_get_perclk1(void) 261 - { 262 - return imx_get_system_clk() / (((PCDR) & 0xf)+1); 263 - } 264 - EXPORT_SYMBOL(imx_get_perclk1); 265 - 266 - /* 267 - * get peripheral clock 2 ( LCD, SD, SPI[12] ) 268 - */ 269 - unsigned int imx_get_perclk2(void) 270 - { 271 - return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); 272 - } 273 - EXPORT_SYMBOL(imx_get_perclk2); 274 - 275 - /* 276 - * get peripheral clock 3 ( SSI ) 277 - */ 278 - unsigned int imx_get_perclk3(void) 279 - { 280 - return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); 281 - } 282 - EXPORT_SYMBOL(imx_get_perclk3); 283 - 284 - /* 285 - * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) 286 - */ 287 - unsigned int imx_get_hclk(void) 288 - { 289 - return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); 290 - } 291 - EXPORT_SYMBOL(imx_get_hclk); 292 - 293 217 static struct resource imx_mmc_resources[] = { 294 218 [0] = { 295 219 .start = 0x00214000,
+18 -7
arch/arm/mach-imx/time.c
··· 17 17 #include <linux/time.h> 18 18 #include <linux/clocksource.h> 19 19 #include <linux/clockchips.h> 20 + #include <linux/clk.h> 20 21 21 22 #include <asm/hardware.h> 22 23 #include <asm/io.h> ··· 87 86 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 88 87 }; 89 88 90 - static int __init imx_clocksource_init(void) 89 + static int __init imx_clocksource_init(unsigned long rate) 91 90 { 92 91 clocksource_imx.mult = 93 - clocksource_hz2mult(imx_get_perclk1(), clocksource_imx.shift); 92 + clocksource_hz2mult(rate, clocksource_imx.shift); 94 93 clocksource_register(&clocksource_imx); 95 94 96 95 return 0; ··· 175 174 .rating = 200, 176 175 }; 177 176 178 - static int __init imx_clockevent_init(void) 177 + static int __init imx_clockevent_init(unsigned long rate) 179 178 { 180 - clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC, 179 + clockevent_imx.mult = div_sc(rate, NSEC_PER_SEC, 181 180 clockevent_imx.shift); 182 181 clockevent_imx.max_delta_ns = 183 182 clockevent_delta2ns(0xfffffffe, &clockevent_imx); ··· 191 190 return 0; 192 191 } 193 192 193 + extern int imx_clocks_init(void); 194 194 195 195 static void __init imx_timer_init(void) 196 196 { 197 - imx_timer_hardware_init(); 198 - imx_clocksource_init(); 197 + struct clk *clk; 198 + unsigned long rate; 199 199 200 - imx_clockevent_init(); 200 + imx_clocks_init(); 201 + 202 + clk = clk_get(NULL, "perclk1"); 203 + clk_enable(clk); 204 + rate = clk_get_rate(clk); 205 + 206 + imx_timer_hardware_init(); 207 + imx_clocksource_init(rate); 208 + 209 + imx_clockevent_init(rate); 201 210 202 211 /* 203 212 * Make irqs happen for the system timer
+18 -1
drivers/mmc/host/imxmmc.c
··· 42 42 #include <linux/mmc/host.h> 43 43 #include <linux/mmc/card.h> 44 44 #include <linux/delay.h> 45 + #include <linux/clk.h> 45 46 46 47 #include <asm/dma.h> 47 48 #include <asm/io.h> ··· 93 92 unsigned char actual_bus_width; 94 93 95 94 int prev_cmd_code; 95 + 96 + struct clk *clk; 96 97 }; 97 98 98 99 #define IMXMCI_PEND_IRQ_b 0 ··· 844 841 /* The prescaler is 5 for PERCLK2 equal to 96MHz 845 842 * then 96MHz / 5 = 19.2 MHz 846 843 */ 847 - clk=imx_get_perclk2(); 844 + clk = clk_get_rate(host->clk); 848 845 prescaler=(clk+(CLK_RATE*7)/8)/CLK_RATE; 849 846 switch(prescaler) { 850 847 case 0: ··· 997 994 host->res = r; 998 995 host->irq = irq; 999 996 997 + host->clk = clk_get(&pdev->dev, "perclk2"); 998 + if (IS_ERR(host->clk)) { 999 + ret = PTR_ERR(host->clk); 1000 + goto out; 1001 + } 1002 + clk_enable(host->clk); 1003 + 1000 1004 imx_gpio_mode(PB8_PF_SD_DAT0); 1001 1005 imx_gpio_mode(PB9_PF_SD_DAT1); 1002 1006 imx_gpio_mode(PB10_PF_SD_DAT2); ··· 1063 1053 imx_dma_free(host->dma); 1064 1054 host->dma_allocated=0; 1065 1055 } 1056 + if (host->clk) { 1057 + clk_disable(host->clk); 1058 + clk_put(host->clk); 1059 + } 1066 1060 } 1067 1061 if (mmc) 1068 1062 mmc_free_host(mmc); ··· 1095 1081 } 1096 1082 1097 1083 tasklet_kill(&host->tasklet); 1084 + 1085 + clk_disable(host->clk); 1086 + clk_put(host->clk); 1098 1087 1099 1088 release_resource(host->res); 1100 1089
+21 -4
drivers/serial/imx.c
··· 40 40 #include <linux/tty_flip.h> 41 41 #include <linux/serial_core.h> 42 42 #include <linux/serial.h> 43 + #include <linux/clk.h> 43 44 44 45 #include <asm/io.h> 45 46 #include <asm/irq.h> ··· 185 184 unsigned int old_status; 186 185 int txirq,rxirq,rtsirq; 187 186 int have_rtscts:1; 187 + struct clk *clk; 188 188 }; 189 189 190 190 /* ··· 481 479 * RFDIV is set such way to satisfy requested uartclk value 482 480 */ 483 481 val = TXTL << 10 | RXTL; 484 - ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; 482 + ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2) 483 + / sport->port.uartclk; 485 484 486 485 if(!ufcr_rfdiv) 487 486 ufcr_rfdiv = 1; ··· 919 916 else 920 917 ucfr_rfdiv = 6 - ucfr_rfdiv; 921 918 922 - uartclk = imx_get_perclk1(); 919 + uartclk = clk_get_rate(sport->clk); 923 920 uartclk /= ucfr_rfdiv; 924 921 925 922 { /* ··· 1057 1054 init_timer(&sport->timer); 1058 1055 sport->timer.function = imx_timeout; 1059 1056 sport->timer.data = (unsigned long)sport; 1060 - sport->port.uartclk = imx_get_perclk1(); 1057 + 1058 + sport->clk = clk_get(&pdev->dev, "uart_clk"); 1059 + if (IS_ERR(sport->clk)) { 1060 + ret = PTR_ERR(sport->clk); 1061 + goto unmap; 1062 + } 1063 + clk_enable(sport->clk); 1064 + 1065 + sport->port.uartclk = clk_get_rate(sport->clk); 1061 1066 1062 1067 imx_ports[pdev->id] = sport; 1063 1068 ··· 1080 1069 platform_set_drvdata(pdev, &sport->port); 1081 1070 1082 1071 return 0; 1072 + unmap: 1073 + iounmap(sport->port.membase); 1083 1074 free: 1084 1075 kfree(sport); 1085 1076 ··· 1097 1084 1098 1085 platform_set_drvdata(pdev, NULL); 1099 1086 1100 - if (sport) 1087 + if (sport) { 1101 1088 uart_remove_one_port(&imx_reg, &sport->port); 1089 + clk_put(sport->clk); 1090 + } 1091 + 1092 + clk_disable(sport->clk); 1102 1093 1103 1094 if (pdata->exit) 1104 1095 pdata->exit(pdev);
+28 -10
drivers/spi/spi_imx.c
··· 29 29 #include <linux/spi/spi.h> 30 30 #include <linux/workqueue.h> 31 31 #include <linux/delay.h> 32 + #include <linux/clk.h> 32 33 33 34 #include <asm/io.h> 34 35 #include <asm/irq.h> ··· 251 250 int tx_dma_needs_unmap; 252 251 size_t tx_map_len; 253 252 u32 dummy_dma_buf ____cacheline_aligned; 253 + 254 + struct clk *clk; 254 255 }; 255 256 256 257 /* Runtime state */ ··· 858 855 return drv_data->transfer_handler(drv_data); 859 856 } 860 857 861 - static inline u32 spi_speed_hz(u32 data_rate) 858 + static inline u32 spi_speed_hz(struct driver_data *drv_data, u32 data_rate) 862 859 { 863 - return imx_get_perclk2() / (4 << ((data_rate) >> 13)); 860 + return clk_get_rate(drv_data->clk) / (4 << ((data_rate) >> 13)); 864 861 } 865 862 866 - static u32 spi_data_rate(u32 speed_hz) 863 + static u32 spi_data_rate(struct driver_data *drv_data, u32 speed_hz) 867 864 { 868 865 u32 div; 869 - u32 quantized_hz = imx_get_perclk2() >> 2; 866 + u32 quantized_hz = clk_get_rate(drv_data->clk) >> 2; 870 867 871 868 for (div = SPI_PERCLK2_DIV_MIN; 872 869 div <= SPI_PERCLK2_DIV_MAX; ··· 950 947 tmp = transfer->speed_hz; 951 948 if (tmp == 0) 952 949 tmp = chip->max_speed_hz; 953 - tmp = spi_data_rate(tmp); 950 + tmp = spi_data_rate(drv_data, tmp); 954 951 u32_EDIT(control, SPI_CONTROL_DATARATE, tmp); 955 952 956 953 writel(control, regs + SPI_CONTROL); ··· 1112 1109 msg->actual_length = 0; 1113 1110 1114 1111 /* Per transfer setup check */ 1115 - min_speed_hz = spi_speed_hz(SPI_CONTROL_DATARATE_MIN); 1112 + min_speed_hz = spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN); 1116 1113 max_speed_hz = spi->max_speed_hz; 1117 1114 list_for_each_entry(trans, &msg->transfers, transfer_list) { 1118 1115 tmp = trans->bits_per_word; ··· 1179 1176 applied and notified to the calling driver. */ 1180 1177 static int setup(struct spi_device *spi) 1181 1178 { 1179 + struct driver_data *drv_data = spi_master_get_devdata(spi->master); 1182 1180 struct spi_imx_chip *chip_info; 1183 1181 struct chip_data *chip; 1184 1182 int first_setup = 0; ··· 1308 1304 chip->n_bytes = (tmp <= 8) ? 1 : 2; 1309 1305 1310 1306 /* SPI datarate */ 1311 - tmp = spi_data_rate(spi->max_speed_hz); 1307 + tmp = spi_data_rate(drv_data, spi->max_speed_hz); 1312 1308 if (tmp == SPI_CONTROL_DATARATE_BAD) { 1313 1309 status = -EINVAL; 1314 1310 dev_err(&spi->dev, 1315 1311 "setup - " 1316 1312 "HW min speed (%d Hz) exceeds required " 1317 1313 "max speed (%d Hz)\n", 1318 - spi_speed_hz(SPI_CONTROL_DATARATE_MIN), 1314 + spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN), 1319 1315 spi->max_speed_hz); 1320 1316 if (first_setup) 1321 1317 goto err_first_setup; ··· 1325 1321 } else { 1326 1322 u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp); 1327 1323 /* Actual rounded max_speed_hz */ 1328 - tmp = spi_speed_hz(tmp); 1324 + tmp = spi_speed_hz(drv_data, tmp); 1329 1325 spi->max_speed_hz = tmp; 1330 1326 chip->max_speed_hz = tmp; 1331 1327 } ··· 1356 1352 chip->period & SPI_PERIOD_WAIT, 1357 1353 spi->mode, 1358 1354 spi->bits_per_word, 1359 - spi_speed_hz(SPI_CONTROL_DATARATE_MIN), 1355 + spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN), 1360 1356 spi->max_speed_hz); 1361 1357 return status; 1362 1358 ··· 1468 1464 status = -ENODEV; 1469 1465 goto err_no_pdata; 1470 1466 } 1467 + 1468 + drv_data->clk = clk_get(&pdev->dev, "perclk2"); 1469 + if (IS_ERR(drv_data->clk)) { 1470 + dev_err(&pdev->dev, "probe - cannot get get\n"); 1471 + status = PTR_ERR(drv_data->clk); 1472 + goto err_no_clk; 1473 + } 1474 + clk_enable(drv_data->clk); 1471 1475 1472 1476 /* Allocate master with space for drv_data */ 1473 1477 master = spi_alloc_master(dev, sizeof(struct driver_data)); ··· 1635 1623 spi_master_put(master); 1636 1624 1637 1625 err_no_pdata: 1626 + clk_disable(drv_data->clk); 1627 + clk_put(drv_data->clk); 1628 + err_no_clk: 1638 1629 err_no_mem: 1639 1630 return status; 1640 1631 } ··· 1676 1661 irq = platform_get_irq(pdev, 0); 1677 1662 if (irq >= 0) 1678 1663 free_irq(irq, drv_data); 1664 + 1665 + clk_disable(drv_data->clk); 1666 + clk_put(drv_data->clk); 1679 1667 1680 1668 /* Release map resources */ 1681 1669 iounmap(drv_data->regs);
-8
include/asm-arm/arch-imx/hardware.h
··· 73 73 */ 74 74 extern void imx_gpio_mode( int gpio_mode ); 75 75 76 - /* get frequencies in Hz */ 77 - extern unsigned int imx_get_system_clk(void); 78 - extern unsigned int imx_get_mcu_clk(void); 79 - extern unsigned int imx_get_perclk1(void); /* UART[12], Timer[12], PWM */ 80 - extern unsigned int imx_get_perclk2(void); /* LCD, SD, SPI[12] */ 81 - extern unsigned int imx_get_perclk3(void); /* SSI */ 82 - extern unsigned int imx_get_hclk(void); /* SDRAM, CSI, Memory Stick,*/ 83 - /* I2C, DMA */ 84 76 #endif 85 77 86 78 #define MAXIRQNUM 62