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>
This commit is contained in:
commit
89bfd48d67
|
@ -55,6 +55,7 @@ struct clk_plt_data {
|
||||||
u8 nparents;
|
u8 nparents;
|
||||||
struct clk_plt *clks[PMC_CLK_NUM];
|
struct clk_plt *clks[PMC_CLK_NUM];
|
||||||
struct clk_lookup *mclk_lookup;
|
struct clk_lookup *mclk_lookup;
|
||||||
|
struct clk_lookup *ether_clk_lookup;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return an index in parent table */
|
/* Return an index in parent table */
|
||||||
|
@ -186,13 +187,6 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
|
||||||
pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
|
pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
|
||||||
spin_lock_init(&pclk->lock);
|
spin_lock_init(&pclk->lock);
|
||||||
|
|
||||||
/*
|
|
||||||
* If the clock was already enabled by the firmware mark it as critical
|
|
||||||
* to avoid it being gated by the clock framework if no driver owns it.
|
|
||||||
*/
|
|
||||||
if (plt_clk_is_enabled(&pclk->hw))
|
|
||||||
init.flags |= CLK_IS_CRITICAL;
|
|
||||||
|
|
||||||
ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
|
ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pclk = ERR_PTR(ret);
|
pclk = ERR_PTR(ret);
|
||||||
|
@ -351,11 +345,20 @@ static int plt_clk_probe(struct platform_device *pdev)
|
||||||
goto err_unreg_clk_plt;
|
goto err_unreg_clk_plt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data->ether_clk_lookup = clkdev_hw_create(&data->clks[4]->hw,
|
||||||
|
"ether_clk", NULL);
|
||||||
|
if (!data->ether_clk_lookup) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_drop_mclk;
|
||||||
|
}
|
||||||
|
|
||||||
plt_clk_free_parent_names_loop(parent_names, data->nparents);
|
plt_clk_free_parent_names_loop(parent_names, data->nparents);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, data);
|
platform_set_drvdata(pdev, data);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_drop_mclk:
|
||||||
|
clkdev_drop(data->mclk_lookup);
|
||||||
err_unreg_clk_plt:
|
err_unreg_clk_plt:
|
||||||
plt_clk_unregister_loop(data, i);
|
plt_clk_unregister_loop(data, i);
|
||||||
plt_clk_unregister_parents(data);
|
plt_clk_unregister_parents(data);
|
||||||
|
@ -369,6 +372,7 @@ static int plt_clk_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
data = platform_get_drvdata(pdev);
|
data = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
clkdev_drop(data->ether_clk_lookup);
|
||||||
clkdev_drop(data->mclk_lookup);
|
clkdev_drop(data->mclk_lookup);
|
||||||
plt_clk_unregister_loop(data, PMC_CLK_NUM);
|
plt_clk_unregister_loop(data, PMC_CLK_NUM);
|
||||||
plt_clk_unregister_parents(data);
|
plt_clk_unregister_parents(data);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
|
@ -665,6 +666,7 @@ struct rtl8169_private {
|
||||||
|
|
||||||
u16 event_slow;
|
u16 event_slow;
|
||||||
const struct rtl_coalesce_info *coalesce_info;
|
const struct rtl_coalesce_info *coalesce_info;
|
||||||
|
struct clk *clk;
|
||||||
|
|
||||||
struct mdio_ops {
|
struct mdio_ops {
|
||||||
void (*write)(struct rtl8169_private *, int, int);
|
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)
|
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;
|
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->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
|
||||||
tp->supports_gmii = cfg->has_gmii;
|
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) */
|
/* enable device (incl. PCI PM wakeup and hotplug setup) */
|
||||||
rc = pcim_enable_device(pdev);
|
rc = pcim_enable_device(pdev);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
|
Loading…
Reference in New Issue