Skip to content

Commit 89bfd48

Browse files
committed
Merge branch 'r8169-clk-fixes'
Hans de Goede says: ==================== r8169 (x86) clk fixes to fix S0ix not being reached This series adds code to the r8169 ethernet driver to get and enable an external clock if present, avoiding the need for a hack in the clk-pmc-atom driver where that clock was left on continuesly causing x86 some devices to not reach deep power saving states (S0ix) when suspended causing to them to quickly drain their battery while suspended. The 3 commits in this series need to be merged in order to avoid regressions while bisecting. The clk-pmc-atom driver does not see much changes (it was last touched over a year ago). So the clk maintainers have agreed with merging all 3 patches through the net tree. All 3 patches have Stephen Boyd's Acked-by for this purpose. This v2 of the series only had some minor tweaks done to the commit messages and is ready for merging through the net tree now. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 0866cd1 + 648e921 commit 89bfd48

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

drivers/clk/x86/clk-pmc-atom.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct clk_plt_data {
5555
u8 nparents;
5656
struct clk_plt *clks[PMC_CLK_NUM];
5757
struct clk_lookup *mclk_lookup;
58+
struct clk_lookup *ether_clk_lookup;
5859
};
5960

6061
/* Return an index in parent table */
@@ -186,13 +187,6 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
186187
pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
187188
spin_lock_init(&pclk->lock);
188189

189-
/*
190-
* If the clock was already enabled by the firmware mark it as critical
191-
* to avoid it being gated by the clock framework if no driver owns it.
192-
*/
193-
if (plt_clk_is_enabled(&pclk->hw))
194-
init.flags |= CLK_IS_CRITICAL;
195-
196190
ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
197191
if (ret) {
198192
pclk = ERR_PTR(ret);
@@ -351,11 +345,20 @@ static int plt_clk_probe(struct platform_device *pdev)
351345
goto err_unreg_clk_plt;
352346
}
353347

348+
data->ether_clk_lookup = clkdev_hw_create(&data->clks[4]->hw,
349+
"ether_clk", NULL);
350+
if (!data->ether_clk_lookup) {
351+
err = -ENOMEM;
352+
goto err_drop_mclk;
353+
}
354+
354355
plt_clk_free_parent_names_loop(parent_names, data->nparents);
355356

356357
platform_set_drvdata(pdev, data);
357358
return 0;
358359

360+
err_drop_mclk:
361+
clkdev_drop(data->mclk_lookup);
359362
err_unreg_clk_plt:
360363
plt_clk_unregister_loop(data, i);
361364
plt_clk_unregister_parents(data);
@@ -369,6 +372,7 @@ static int plt_clk_remove(struct platform_device *pdev)
369372

370373
data = platform_get_drvdata(pdev);
371374

375+
clkdev_drop(data->ether_clk_lookup);
372376
clkdev_drop(data->mclk_lookup);
373377
plt_clk_unregister_loop(data, PMC_CLK_NUM);
374378
plt_clk_unregister_parents(data);

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)