This pull request contains fixes for the following issues

1) Fix two instances of infinite loop occurring in
    clock list for DA850. This fixes kernel hangs in some
    instances and so have been marked for stable kernel.
 
 2) Fix for sleeping function called from atomic context
    with USB 2.0 clock management code introduced in v4.10
    merge window.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJYbOM8AAoJEGFBu2jqvgRNxTIP/iRuN6cWbJLNB/X7+Pj0LZOJ
 aTOhvPB1wt0raMc93a63DamaD9Y274IDnn/dKh55VBzC3Ctn7sbihOcoOkksHOfj
 6u4oYld1uDpcqzY4IgpxShZzRDNLWYWhKvZwRNwv9XBwFqwM5PCLkdBgr7/Obwcf
 69ziK9IyErmruZCnsOCeeG7YaOPA3reOvEq+1wS9Hy7V1Dh0DERdU9dx3SmHi3Jp
 CBpx7mdaF/VYTyhlTAuKS+VZYiVbGW53rVMNVcNxoPVnh/eDuafgqoXW6U87fmcM
 d3SOQlcrd/dneIFej2Y0v6ppqyw1XB5PXRJCcK2YPIBz2lHiviEtnfct6HIqWD53
 tl+I1GNgoHihxcSqsy8y4d55SLnbfCvz0JVr6PvncObOqDee/6LL0dovqRuHzFKT
 fyWviWujRzmeDb8sPElyxWdOvofM+4akETwGfCq2IrL15yNW5EYPAQxhbZezuWFM
 X/hXLUP1NXysHNltJMmvyxTTQH7DfpPFX+Ct5vb7Uqkq+LhAgtuoZrxQFaYJP28P
 4wIe2XXt6ZsHAbHA7TdnaJMDY+/WzsGz7rEeebzw1xRPMkkV7NUbyx+5gQPGuLDm
 duvLxdG6mt0nzPOFw8v5ShB8GTFm2iD8S8CRoOxIfF/JVtn1YJCE/w395XSWBPjj
 NgqTMhuP+CV2jHBkMYlS
 =mX5P
 -----END PGP SIGNATURE-----

Merge tag 'davinci-fixes-for-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci into fixes

Pull "DaVinci fixes for v4.10" from Sekhar Nori:

This pull request contains fixes for the following issues

1) Fix two instances of infinite loop occurring in
   clock list for DA850. This fixes kernel hangs in some
   instances and so have been marked for stable kernel.

2) Fix for sleeping function called from atomic context
   with USB 2.0 clock management code introduced in v4.10
   merge window.

* tag 'davinci-fixes-for-v4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci:
  ARM: davinci: da8xx: Fix sleeping function called from invalid context
  ARM: davinci: Make __clk_{enable,disable} functions public
  ARM: davinci: da850: don't add emac clock to lookup table twice
  ARM: davinci: da850: fix infinite loop in clk_set_rate()
This commit is contained in:
Arnd Bergmann 2017-01-04 16:43:00 +01:00
commit 1b9ec81258
4 changed files with 53 additions and 27 deletions

View File

@ -31,10 +31,10 @@ static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clockfw_lock);
static void __clk_enable(struct clk *clk)
void davinci_clk_enable(struct clk *clk)
{
if (clk->parent)
__clk_enable(clk->parent);
davinci_clk_enable(clk->parent);
if (clk->usecount++ == 0) {
if (clk->flags & CLK_PSC)
davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
@ -44,7 +44,7 @@ static void __clk_enable(struct clk *clk)
}
}
static void __clk_disable(struct clk *clk)
void davinci_clk_disable(struct clk *clk)
{
if (WARN_ON(clk->usecount == 0))
return;
@ -56,7 +56,7 @@ static void __clk_disable(struct clk *clk)
clk->clk_disable(clk);
}
if (clk->parent)
__clk_disable(clk->parent);
davinci_clk_disable(clk->parent);
}
int davinci_clk_reset(struct clk *clk, bool reset)
@ -103,7 +103,7 @@ int clk_enable(struct clk *clk)
return -EINVAL;
spin_lock_irqsave(&clockfw_lock, flags);
__clk_enable(clk);
davinci_clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
return 0;
@ -118,7 +118,7 @@ void clk_disable(struct clk *clk)
return;
spin_lock_irqsave(&clockfw_lock, flags);
__clk_disable(clk);
davinci_clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_disable);

View File

@ -132,6 +132,8 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
int davinci_set_refclk_rate(unsigned long rate);
int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
int davinci_clk_reset(struct clk *clk, bool reset);
void davinci_clk_enable(struct clk *clk);
void davinci_clk_disable(struct clk *clk);
extern struct platform_device davinci_wdt_device;
extern void davinci_watchdog_reset(struct platform_device *);

View File

@ -319,6 +319,16 @@ static struct clk emac_clk = {
.gpsc = 1,
};
/*
* In order to avoid adding the emac_clk to the clock lookup table twice (and
* screwing up the linked list in the process) create a separate clock for
* mdio inheriting the rate from emac_clk.
*/
static struct clk mdio_clk = {
.name = "mdio",
.parent = &emac_clk,
};
static struct clk mcasp_clk = {
.name = "mcasp",
.parent = &async3_clk,
@ -367,6 +377,16 @@ static struct clk aemif_clk = {
.flags = ALWAYS_ENABLED,
};
/*
* In order to avoid adding the aemif_clk to the clock lookup table twice (and
* screwing up the linked list in the process) create a separate clock for
* nand inheriting the rate from aemif_clk.
*/
static struct clk aemif_nand_clk = {
.name = "nand",
.parent = &aemif_clk,
};
static struct clk usb11_clk = {
.name = "usb11",
.parent = &pll0_sysclk4,
@ -529,7 +549,7 @@ static struct clk_lookup da850_clks[] = {
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "rmii", &rmii_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
CLK("davinci_mdio.0", "fck", &emac_clk),
CLK("davinci_mdio.0", "fck", &mdio_clk),
CLK("davinci-mcasp.0", NULL, &mcasp_clk),
CLK("davinci-mcbsp.0", NULL, &mcbsp0_clk),
CLK("davinci-mcbsp.1", NULL, &mcbsp1_clk),
@ -537,7 +557,15 @@ static struct clk_lookup da850_clks[] = {
CLK("da830-mmc.0", NULL, &mmcsd0_clk),
CLK("da830-mmc.1", NULL, &mmcsd1_clk),
CLK("ti-aemif", NULL, &aemif_clk),
CLK(NULL, "aemif", &aemif_clk),
/*
* The only user of this clock is davinci_nand and it get's it through
* con_id. The nand node itself is created from within the aemif
* driver to guarantee that it's probed after the aemif timing
* parameters are configured. of_dev_auxdata is not accessible from
* the aemif driver and can't be passed to of_platform_populate(). For
* that reason we're leaving the dev_id here as NULL.
*/
CLK(NULL, "aemif", &aemif_nand_clk),
CLK("ohci-da8xx", "usb11", &usb11_clk),
CLK("musb-da8xx", "usb20", &usb20_clk),
CLK("spi_davinci.0", NULL, &spi0_clk),

View File

@ -22,6 +22,8 @@
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
static struct clk *usb20_clk;
static struct platform_device da8xx_usb_phy = {
.name = "da8xx-usb-phy",
.id = -1,
@ -158,26 +160,13 @@ int __init da8xx_register_usb_refclkin(int rate)
static void usb20_phy_clk_enable(struct clk *clk)
{
struct clk *usb20_clk;
int err;
u32 val;
u32 timeout = 500000; /* 500 msec */
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
if (IS_ERR(usb20_clk)) {
pr_err("could not get usb20 clk: %ld\n", PTR_ERR(usb20_clk));
return;
}
/* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
err = clk_prepare_enable(usb20_clk);
if (err) {
pr_err("failed to enable usb20 clk: %d\n", err);
clk_put(usb20_clk);
return;
}
davinci_clk_enable(usb20_clk);
/*
* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
@ -197,8 +186,7 @@ static void usb20_phy_clk_enable(struct clk *clk)
pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
done:
clk_disable_unprepare(usb20_clk);
clk_put(usb20_clk);
davinci_clk_disable(usb20_clk);
}
static void usb20_phy_clk_disable(struct clk *clk)
@ -285,11 +273,19 @@ static struct clk_lookup usb20_phy_clk_lookup =
int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
{
struct clk *parent;
int ret = 0;
int ret;
usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
ret = PTR_ERR_OR_ZERO(usb20_clk);
if (ret)
return ret;
parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
if (IS_ERR(parent))
return PTR_ERR(parent);
ret = PTR_ERR_OR_ZERO(parent);
if (ret) {
clk_put(usb20_clk);
return ret;
}
usb20_phy_clk.parent = parent;
ret = clk_register(&usb20_phy_clk);