Skip to content

Commit c2f6f3e

Browse files
jwrdegoededavem330
authored andcommitted
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 d31fd43 ("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: Johannes Stezenbach <js@sig21.net> Acked-by: Stephen Boyd <sboyd@kernel.org> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent b1e3454 commit c2f6f3e

File tree

1 file changed

+33
-0
lines changed
  • drivers/net/ethernet/realtek

1 file changed

+33
-0
lines changed

drivers/net/ethernet/realtek/r8169.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/pci.h>
1414
#include <linux/netdevice.h>
1515
#include <linux/etherdevice.h>
16+
#include <linux/clk.h>
1617
#include <linux/delay.h>
1718
#include <linux/ethtool.h>
1819
#include <linux/phy.h>
@@ -665,6 +666,7 @@ struct rtl8169_private {
665666

666667
u16 event_slow;
667668
const struct rtl_coalesce_info *coalesce_info;
669+
struct clk *clk;
668670

669671
struct mdio_ops {
670672
void (*write)(struct rtl8169_private *, int, int);
@@ -7262,6 +7264,11 @@ static int rtl_jumbo_max(struct rtl8169_private *tp)
72627264
}
72637265
}
72647266

7267+
static void rtl_disable_clk(void *data)
7268+
{
7269+
clk_disable_unprepare(data);
7270+
}
7271+
72657272
static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
72667273
{
72677274
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)
72827289
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
72837290
tp->supports_gmii = cfg->has_gmii;
72847291

7292+
/* Get the *optional* external "ether_clk" used on some boards */
7293+
tp->clk = devm_clk_get(&pdev->dev, "ether_clk");
7294+
if (IS_ERR(tp->clk)) {
7295+
rc = PTR_ERR(tp->clk);
7296+
if (rc == -ENOENT) {
7297+
/* clk-core allows NULL (for suspend / resume) */
7298+
tp->clk = NULL;
7299+
} else if (rc == -EPROBE_DEFER) {
7300+
return rc;
7301+
} else {
7302+
dev_err(&pdev->dev, "failed to get clk: %d\n", rc);
7303+
return rc;
7304+
}
7305+
} else {
7306+
rc = clk_prepare_enable(tp->clk);
7307+
if (rc) {
7308+
dev_err(&pdev->dev, "failed to enable clk: %d\n", rc);
7309+
return rc;
7310+
}
7311+
7312+
rc = devm_add_action_or_reset(&pdev->dev, rtl_disable_clk,
7313+
tp->clk);
7314+
if (rc)
7315+
return rc;
7316+
}
7317+
72857318
/* enable device (incl. PCI PM wakeup and hotplug setup) */
72867319
rc = pcim_enable_device(pdev);
72877320
if (rc < 0) {

0 commit comments

Comments
 (0)