summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/serial/tegra_hsuart.c14
-rw-r--r--include/linux/tegra_uart.h12
2 files changed, 26 insertions, 0 deletions
diff --git a/drivers/serial/tegra_hsuart.c b/drivers/serial/tegra_hsuart.c
index 3709162e67dd..078e2965fafc 100644
--- a/drivers/serial/tegra_hsuart.c
+++ b/drivers/serial/tegra_hsuart.c
@@ -1076,14 +1076,20 @@ static unsigned long find_best_clock_source(struct tegra_uart_port *t,
unsigned long fin_rate = rate;
int final_index = -1;
int count;
+ unsigned long error_2perc;
pdata = u->dev->platform_data;
if (!pdata || !pdata->parent_clk_count)
return fin_rate;
+ error_2perc = (rate / 50);
+
for (count = 0; count < pdata->parent_clk_count; ++count) {
parent_rate = pdata->parent_clk_list[count].fixed_clk_rate;
+ if (parent_rate < rate)
+ continue;
+
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
divider = clk_div71_get_divider(parent_rate, rate);
@@ -1097,8 +1103,12 @@ static unsigned long find_best_clock_source(struct tegra_uart_port *t,
final_index = count;
fin_err = err_rate;
fin_rate = new_rate;
+ if (fin_err < error_2perc)
+ break;
}
}
+ if (fin_err < error_2perc)
+ break;
}
#endif
/* Get the divisor by uart controller dll/dlm */
@@ -1113,8 +1123,12 @@ static unsigned long find_best_clock_source(struct tegra_uart_port *t,
final_index = count;
fin_err = err_rate;
fin_rate = parent_rate;
+ if (fin_err < error_2perc)
+ break;
}
}
+ if (fin_err < error_2perc)
+ break;
}
}
diff --git a/include/linux/tegra_uart.h b/include/linux/tegra_uart.h
index 3d35e217cbca..42d981982b64 100644
--- a/include/linux/tegra_uart.h
+++ b/include/linux/tegra_uart.h
@@ -28,6 +28,18 @@ struct uart_clk_parent {
unsigned long fixed_clk_rate;
};
+/*
+ * struct tegra_uart_platform_data - Platform data for tegra high speed uart.
+ *
+ * @parent_clk_list: The parent clock source list. The best clock source will be
+ * selected such that the error between desired baudrate and
+ * calculated baudrate within 2% error. The searching will
+ * start from index 0 and so the preference of clock source
+ * selection will be high on index 0 and it will go lower
+ * with increasing index.
+ * @parent_clk_count: The number of clock source list.
+ */
+
struct tegra_uart_platform_data {
void (*wake_peer)(struct uart_port *);
struct uart_clk_parent *parent_clk_list;