diff options
-rw-r--r-- | drivers/tty/serial/max310x.c | 86 | ||||
-rw-r--r-- | include/linux/platform_data/max310x.h | 7 |
2 files changed, 55 insertions, 38 deletions
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 9e147f3d7291..310ee555fade 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
20 | #include <linux/clk.h> | ||
20 | #include <linux/serial_core.h> | 21 | #include <linux/serial_core.h> |
21 | #include <linux/serial.h> | 22 | #include <linux/serial.h> |
22 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
@@ -291,6 +292,7 @@ struct max310x_port { | |||
291 | struct max310x_devtype *devtype; | 292 | struct max310x_devtype *devtype; |
292 | struct regmap *regmap; | 293 | struct regmap *regmap; |
293 | struct mutex mutex; | 294 | struct mutex mutex; |
295 | struct clk *clk; | ||
294 | struct max310x_pdata *pdata; | 296 | struct max310x_pdata *pdata; |
295 | int gpio_used; | 297 | int gpio_used; |
296 | #ifdef CONFIG_GPIOLIB | 298 | #ifdef CONFIG_GPIOLIB |
@@ -546,18 +548,19 @@ static int max310x_update_best_err(unsigned long f, long *besterr) | |||
546 | return 1; | 548 | return 1; |
547 | } | 549 | } |
548 | 550 | ||
549 | static int max310x_set_ref_clk(struct max310x_port *s) | 551 | static int max310x_set_ref_clk(struct max310x_port *s, unsigned long freq, |
552 | bool xtal) | ||
550 | { | 553 | { |
551 | unsigned int div, clksrc, pllcfg = 0; | 554 | unsigned int div, clksrc, pllcfg = 0; |
552 | long besterr = -1; | 555 | long besterr = -1; |
553 | unsigned long fdiv, fmul, bestfreq = s->pdata->frequency; | 556 | unsigned long fdiv, fmul, bestfreq = freq; |
554 | 557 | ||
555 | /* First, update error without PLL */ | 558 | /* First, update error without PLL */ |
556 | max310x_update_best_err(s->pdata->frequency, &besterr); | 559 | max310x_update_best_err(freq, &besterr); |
557 | 560 | ||
558 | /* Try all possible PLL dividers */ | 561 | /* Try all possible PLL dividers */ |
559 | for (div = 1; (div <= 63) && besterr; div++) { | 562 | for (div = 1; (div <= 63) && besterr; div++) { |
560 | fdiv = DIV_ROUND_CLOSEST(s->pdata->frequency, div); | 563 | fdiv = DIV_ROUND_CLOSEST(freq, div); |
561 | 564 | ||
562 | /* Try multiplier 6 */ | 565 | /* Try multiplier 6 */ |
563 | fmul = fdiv * 6; | 566 | fmul = fdiv * 6; |
@@ -590,10 +593,7 @@ static int max310x_set_ref_clk(struct max310x_port *s) | |||
590 | } | 593 | } |
591 | 594 | ||
592 | /* Configure clock source */ | 595 | /* Configure clock source */ |
593 | if (s->pdata->driver_flags & MAX310X_EXT_CLK) | 596 | clksrc = xtal ? MAX310X_CLKSRC_CRYST_BIT : MAX310X_CLKSRC_EXTCLK_BIT; |
594 | clksrc = MAX310X_CLKSRC_EXTCLK_BIT; | ||
595 | else | ||
596 | clksrc = MAX310X_CLKSRC_CRYST_BIT; | ||
597 | 597 | ||
598 | /* Configure PLL */ | 598 | /* Configure PLL */ |
599 | if (pllcfg) { | 599 | if (pllcfg) { |
@@ -605,7 +605,7 @@ static int max310x_set_ref_clk(struct max310x_port *s) | |||
605 | regmap_write(s->regmap, MAX310X_CLKSRC_REG, clksrc); | 605 | regmap_write(s->regmap, MAX310X_CLKSRC_REG, clksrc); |
606 | 606 | ||
607 | /* Wait for crystal */ | 607 | /* Wait for crystal */ |
608 | if (pllcfg && !(s->pdata->driver_flags & MAX310X_EXT_CLK)) | 608 | if (pllcfg && xtal) |
609 | msleep(10); | 609 | msleep(10); |
610 | 610 | ||
611 | return (int)bestfreq; | 611 | return (int)bestfreq; |
@@ -1078,9 +1078,11 @@ static int max310x_gpio_direction_output(struct gpio_chip *chip, | |||
1078 | static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | 1078 | static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, |
1079 | struct regmap *regmap, int irq) | 1079 | struct regmap *regmap, int irq) |
1080 | { | 1080 | { |
1081 | struct max310x_port *s; | ||
1082 | struct max310x_pdata *pdata = dev_get_platdata(dev); | 1081 | struct max310x_pdata *pdata = dev_get_platdata(dev); |
1083 | int i, ret, uartclk; | 1082 | int i, ret, fmin, fmax, freq, uartclk; |
1083 | struct clk *clk_osc, *clk_xtal; | ||
1084 | struct max310x_port *s; | ||
1085 | bool xtal = false; | ||
1084 | 1086 | ||
1085 | if (IS_ERR(regmap)) | 1087 | if (IS_ERR(regmap)) |
1086 | return PTR_ERR(regmap); | 1088 | return PTR_ERR(regmap); |
@@ -1098,14 +1100,35 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1098 | return -ENOMEM; | 1100 | return -ENOMEM; |
1099 | } | 1101 | } |
1100 | 1102 | ||
1101 | /* Check input frequency */ | 1103 | clk_osc = devm_clk_get(dev, "osc"); |
1102 | if ((pdata->driver_flags & MAX310X_EXT_CLK) && | 1104 | clk_xtal = devm_clk_get(dev, "xtal"); |
1103 | ((pdata->frequency < 500000) || (pdata->frequency > 35000000))) | 1105 | if (!IS_ERR(clk_osc)) { |
1104 | goto err_freq; | 1106 | s->clk = clk_osc; |
1105 | /* Check frequency for quartz */ | 1107 | fmin = 500000; |
1106 | if (!(pdata->driver_flags & MAX310X_EXT_CLK) && | 1108 | fmax = 35000000; |
1107 | ((pdata->frequency < 1000000) || (pdata->frequency > 4000000))) | 1109 | } else if (!IS_ERR(clk_xtal)) { |
1108 | goto err_freq; | 1110 | s->clk = clk_xtal; |
1111 | fmin = 1000000; | ||
1112 | fmax = 4000000; | ||
1113 | xtal = true; | ||
1114 | } else if (PTR_ERR(clk_osc) == -EPROBE_DEFER || | ||
1115 | PTR_ERR(clk_xtal) == -EPROBE_DEFER) { | ||
1116 | return -EPROBE_DEFER; | ||
1117 | } else { | ||
1118 | dev_err(dev, "Cannot get clock\n"); | ||
1119 | return -EINVAL; | ||
1120 | } | ||
1121 | |||
1122 | ret = clk_prepare_enable(s->clk); | ||
1123 | if (ret) | ||
1124 | return ret; | ||
1125 | |||
1126 | freq = clk_get_rate(s->clk); | ||
1127 | /* Check frequency limits */ | ||
1128 | if (freq < fmin || freq > fmax) { | ||
1129 | ret = -ERANGE; | ||
1130 | goto out_clk; | ||
1131 | } | ||
1109 | 1132 | ||
1110 | s->pdata = pdata; | 1133 | s->pdata = pdata; |
1111 | s->regmap = regmap; | 1134 | s->regmap = regmap; |
@@ -1117,7 +1140,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1117 | /* Check device to ensure we are talking to what we expect */ | 1140 | /* Check device to ensure we are talking to what we expect */ |
1118 | ret = devtype->detect(dev); | 1141 | ret = devtype->detect(dev); |
1119 | if (ret) | 1142 | if (ret) |
1120 | return ret; | 1143 | goto out_clk; |
1121 | 1144 | ||
1122 | for (i = 0; i < devtype->nr; i++) { | 1145 | for (i = 0; i < devtype->nr; i++) { |
1123 | unsigned int offs = i << 5; | 1146 | unsigned int offs = i << 5; |
@@ -1139,7 +1162,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1139 | MAX310X_MODE1_AUTOSLEEP_BIT); | 1162 | MAX310X_MODE1_AUTOSLEEP_BIT); |
1140 | } | 1163 | } |
1141 | 1164 | ||
1142 | uartclk = max310x_set_ref_clk(s); | 1165 | uartclk = max310x_set_ref_clk(s, freq, xtal); |
1143 | dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk); | 1166 | dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk); |
1144 | 1167 | ||
1145 | /* Register UART driver */ | 1168 | /* Register UART driver */ |
@@ -1151,7 +1174,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1151 | ret = uart_register_driver(&s->uart); | 1174 | ret = uart_register_driver(&s->uart); |
1152 | if (ret) { | 1175 | if (ret) { |
1153 | dev_err(dev, "Registering UART driver failed\n"); | 1176 | dev_err(dev, "Registering UART driver failed\n"); |
1154 | return ret; | 1177 | goto out_clk; |
1155 | } | 1178 | } |
1156 | 1179 | ||
1157 | for (i = 0; i < devtype->nr; i++) { | 1180 | for (i = 0; i < devtype->nr; i++) { |
@@ -1208,19 +1231,19 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1208 | ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist, | 1231 | ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist, |
1209 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 1232 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
1210 | dev_name(dev), s); | 1233 | dev_name(dev), s); |
1211 | if (ret) { | 1234 | if (!ret) |
1212 | dev_err(dev, "Unable to reguest IRQ %i\n", irq); | 1235 | return 0; |
1236 | |||
1237 | dev_err(dev, "Unable to reguest IRQ %i\n", irq); | ||
1213 | #ifdef CONFIG_GPIOLIB | 1238 | #ifdef CONFIG_GPIOLIB |
1214 | if (s->gpio_used) | 1239 | if (s->gpio_used) |
1215 | WARN_ON(gpiochip_remove(&s->gpio)); | 1240 | WARN_ON(gpiochip_remove(&s->gpio)); |
1216 | #endif | 1241 | #endif |
1217 | } | ||
1218 | 1242 | ||
1219 | return ret; | 1243 | out_clk: |
1244 | clk_disable_unprepare(s->clk); | ||
1220 | 1245 | ||
1221 | err_freq: | 1246 | return ret; |
1222 | dev_err(dev, "Frequency parameter incorrect\n"); | ||
1223 | return -EINVAL; | ||
1224 | } | 1247 | } |
1225 | 1248 | ||
1226 | static int max310x_remove(struct device *dev) | 1249 | static int max310x_remove(struct device *dev) |
@@ -1236,6 +1259,7 @@ static int max310x_remove(struct device *dev) | |||
1236 | } | 1259 | } |
1237 | 1260 | ||
1238 | uart_unregister_driver(&s->uart); | 1261 | uart_unregister_driver(&s->uart); |
1262 | clk_disable_unprepare(s->clk); | ||
1239 | 1263 | ||
1240 | #ifdef CONFIG_GPIOLIB | 1264 | #ifdef CONFIG_GPIOLIB |
1241 | if (s->gpio_used) | 1265 | if (s->gpio_used) |
diff --git a/include/linux/platform_data/max310x.h b/include/linux/platform_data/max310x.h index 9d5f69b2b57c..57a0cd46b847 100644 --- a/include/linux/platform_data/max310x.h +++ b/include/linux/platform_data/max310x.h | |||
@@ -20,9 +20,7 @@ | |||
20 | * Example board initialization data: | 20 | * Example board initialization data: |
21 | * | 21 | * |
22 | * static struct max310x_pdata max3107_pdata = { | 22 | * static struct max310x_pdata max3107_pdata = { |
23 | * .driver_flags = MAX310X_EXT_CLK, | ||
24 | * .uart_flags[0] = MAX310X_ECHO_SUPRESS | MAX310X_AUTO_DIR_CTRL, | 23 | * .uart_flags[0] = MAX310X_ECHO_SUPRESS | MAX310X_AUTO_DIR_CTRL, |
25 | * .frequency = 3686400, | ||
26 | * .gpio_base = -1, | 24 | * .gpio_base = -1, |
27 | * }; | 25 | * }; |
28 | * | 26 | * |
@@ -41,17 +39,12 @@ | |||
41 | 39 | ||
42 | /* MAX310X platform data structure */ | 40 | /* MAX310X platform data structure */ |
43 | struct max310x_pdata { | 41 | struct max310x_pdata { |
44 | /* Flags global to driver */ | ||
45 | const u8 driver_flags; | ||
46 | #define MAX310X_EXT_CLK (0x00000001) /* External clock enable */ | ||
47 | /* Flags global to UART port */ | 42 | /* Flags global to UART port */ |
48 | const u8 uart_flags[MAX310X_MAX_UARTS]; | 43 | const u8 uart_flags[MAX310X_MAX_UARTS]; |
49 | #define MAX310X_ECHO_SUPRESS (0x00000002) /* Enable echo supress */ | 44 | #define MAX310X_ECHO_SUPRESS (0x00000002) /* Enable echo supress */ |
50 | #define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction | 45 | #define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction |
51 | * control (RS-485) | 46 | * control (RS-485) |
52 | */ | 47 | */ |
53 | /* Frequency (extrenal clock or crystal) */ | ||
54 | const int frequency; | ||
55 | /* GPIO base number (can be negative) */ | 48 | /* GPIO base number (can be negative) */ |
56 | const int gpio_base; | 49 | const int gpio_base; |
57 | }; | 50 | }; |