aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/max310x.c86
-rw-r--r--include/linux/platform_data/max310x.h7
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
549static int max310x_set_ref_clk(struct max310x_port *s) 551static 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,
1078static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, 1078static 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; 1243out_clk:
1244 clk_disable_unprepare(s->clk);
1220 1245
1221err_freq: 1246 return ret;
1222 dev_err(dev, "Frequency parameter incorrect\n");
1223 return -EINVAL;
1224} 1247}
1225 1248
1226static int max310x_remove(struct device *dev) 1249static 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 */
43struct max310x_pdata { 41struct 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};