提交 43d3d092 编写于 作者: U Ulf Hansson 提交者: Marcel Holtmann

Bluetooth: hci_ll: Add support for the external clock

Add support to manage the external clock provided to the WiLink combo chip
as it's needed for any of the transport interfaces.

To avoid breaking platforms not yet specifying the external clock, we make
it optional. In case the clock is successfully fetched during ->probe(),
let's manage it via the ->open|close() callbacks, to make sure the device
get properly powered on/off.

Fixes: ea452678 ("arm64: dts: hikey: Fix WiFi support")
Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
Tested-by: NJohn Stultz <john.stultz@linaro.org>
Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
上级 3c8e42a7
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include <linux/serdev.h> #include <linux/serdev.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/ti_wilink_st.h> #include <linux/ti_wilink_st.h>
#include <linux/clk.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
...@@ -84,6 +85,7 @@ struct ll_device { ...@@ -84,6 +85,7 @@ struct ll_device {
struct hci_uart hu; struct hci_uart hu;
struct serdev_device *serdev; struct serdev_device *serdev;
struct gpio_desc *enable_gpio; struct gpio_desc *enable_gpio;
struct clk *ext_clk;
}; };
struct ll_struct { struct ll_struct {
...@@ -146,8 +148,12 @@ static int ll_open(struct hci_uart *hu) ...@@ -146,8 +148,12 @@ static int ll_open(struct hci_uart *hu)
hu->priv = ll; hu->priv = ll;
if (hu->serdev) if (hu->serdev) {
struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
serdev_device_open(hu->serdev); serdev_device_open(hu->serdev);
if (!IS_ERR(lldev->ext_clk))
clk_prepare_enable(lldev->ext_clk);
}
return 0; return 0;
} }
...@@ -181,6 +187,8 @@ static int ll_close(struct hci_uart *hu) ...@@ -181,6 +187,8 @@ static int ll_close(struct hci_uart *hu)
struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev); struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
gpiod_set_value_cansleep(lldev->enable_gpio, 0); gpiod_set_value_cansleep(lldev->enable_gpio, 0);
clk_disable_unprepare(lldev->ext_clk);
serdev_device_close(hu->serdev); serdev_device_close(hu->serdev);
} }
...@@ -721,6 +729,10 @@ static int hci_ti_probe(struct serdev_device *serdev) ...@@ -721,6 +729,10 @@ static int hci_ti_probe(struct serdev_device *serdev)
if (IS_ERR(lldev->enable_gpio)) if (IS_ERR(lldev->enable_gpio))
return PTR_ERR(lldev->enable_gpio); return PTR_ERR(lldev->enable_gpio);
lldev->ext_clk = devm_clk_get(&serdev->dev, "ext_clock");
if (IS_ERR(lldev->ext_clk) && PTR_ERR(lldev->ext_clk) != -ENOENT)
return PTR_ERR(lldev->ext_clk);
of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed); of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed);
hci_uart_set_speeds(hu, 115200, max_speed); hci_uart_set_speeds(hu, 115200, max_speed);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册