提交 c2f6f3ee 编写于 作者: H Hans de Goede 提交者: David S. Miller

r8169: Get and enable optional ether_clk clock

On some boards a platform clock is used as clock for the r8169 chip,
this commit adds support for getting and enabling this clock (assuming
it has an "ether_clk" alias set on it).

This is related to commit d31fd43c ("clk: x86: Do not gate clocks
enabled by the firmware") which is a previous attempt to fix this for some
x86 boards, but this causes all Cherry Trail SoC using boards to not reach
there lowest power states when suspending.

This commit (together with an atom-pmc-clk driver commit adding the alias)
fixes things properly by making the r8169 get the clock and enable it when
it needs it.

Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=193891#c102
Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=196861
Cc: Johannes Stezenbach <js@sig21.net>
Cc: Carlo Caione <carlo@endlessm.com>
Reported-by: NJohannes Stezenbach <js@sig21.net>
Acked-by: NStephen Boyd <sboyd@kernel.org>
Reviewed-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: NHans de Goede <hdegoede@redhat.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 b1e3454d
......@@ -13,6 +13,7 @@
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/phy.h>
......@@ -665,6 +666,7 @@ struct rtl8169_private {
u16 event_slow;
const struct rtl_coalesce_info *coalesce_info;
struct clk *clk;
struct mdio_ops {
void (*write)(struct rtl8169_private *, int, int);
......@@ -7262,6 +7264,11 @@ static int rtl_jumbo_max(struct rtl8169_private *tp)
}
}
static void rtl_disable_clk(void *data)
{
clk_disable_unprepare(data);
}
static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
......@@ -7282,6 +7289,32 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
tp->supports_gmii = cfg->has_gmii;
/* Get the *optional* external "ether_clk" used on some boards */
tp->clk = devm_clk_get(&pdev->dev, "ether_clk");
if (IS_ERR(tp->clk)) {
rc = PTR_ERR(tp->clk);
if (rc == -ENOENT) {
/* clk-core allows NULL (for suspend / resume) */
tp->clk = NULL;
} else if (rc == -EPROBE_DEFER) {
return rc;
} else {
dev_err(&pdev->dev, "failed to get clk: %d\n", rc);
return rc;
}
} else {
rc = clk_prepare_enable(tp->clk);
if (rc) {
dev_err(&pdev->dev, "failed to enable clk: %d\n", rc);
return rc;
}
rc = devm_add_action_or_reset(&pdev->dev, rtl_disable_clk,
tp->clk);
if (rc)
return rc;
}
/* enable device (incl. PCI PM wakeup and hotplug setup) */
rc = pcim_enable_device(pdev);
if (rc < 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册