Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eee98990 authored by Andrew Lunn's avatar Andrew Lunn Committed by Mike Turquette
Browse files

ARM: Orion: SATA: Add per channel clk/clkdev support.



The Orion kirkwood chips have a gatable clock per SATA channel. Add
code to get and enable this clk if it exists.

Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Tested-by: default avatarJamie Lentin <jm@lentin.co.uk>
Signed-off-by: default avatarMike Turquette <mturquette@linaro.org>
parent 74c33576
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx)

void __init kirkwood_clk_init(void)
{
	struct clk *runit, *ge0, *ge1;
	struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0;

	tclk = clk_register_fixed_rate(NULL, "tclk", NULL,
				       CLK_IS_ROOT, kirkwood_tclk);
@@ -94,8 +94,8 @@ void __init kirkwood_clk_init(void)
	runit = kirkwood_register_gate("runit",  CGC_BIT_RUNIT);
	ge0 = kirkwood_register_gate("ge0",    CGC_BIT_GE0);
	ge1 = kirkwood_register_gate("ge1",    CGC_BIT_GE1);
	kirkwood_register_gate("sata0",  CGC_BIT_SATA0);
	kirkwood_register_gate("sata1",  CGC_BIT_SATA1);
	sata0 = kirkwood_register_gate("sata0",  CGC_BIT_SATA0);
	sata1 = kirkwood_register_gate("sata1",  CGC_BIT_SATA1);
	kirkwood_register_gate("usb0",   CGC_BIT_USB0);
	kirkwood_register_gate("sdio",   CGC_BIT_SDIO);
	kirkwood_register_gate("crypto", CGC_BIT_CRYPTO);
@@ -113,6 +113,8 @@ void __init kirkwood_clk_init(void)
	orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0);
	orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1);
	orion_clkdev_add(NULL, "orion_wdt", tclk);
	orion_clkdev_add("0", "sata_mv.0", sata0);
	orion_clkdev_add("1", "sata_mv.0", sata1);
}

/*****************************************************************************
+36 −4
Original line number Diff line number Diff line
@@ -553,6 +553,7 @@ struct mv_host_priv {

#if defined(CONFIG_HAVE_CLK)
	struct clk		*clk;
	struct clk              **port_clks;
#endif
	/*
	 * These consistent DMA memory pools give us guaranteed
@@ -4027,6 +4028,9 @@ static int mv_platform_probe(struct platform_device *pdev)
	struct resource *res;
	int n_ports = 0;
	int rc;
#if defined(CONFIG_HAVE_CLK)
	int port;
#endif

	ata_print_version_once(&pdev->dev, DRV_VERSION);

@@ -4054,6 +4058,13 @@ static int mv_platform_probe(struct platform_device *pdev)

	if (!host || !hpriv)
		return -ENOMEM;
#if defined(CONFIG_HAVE_CLK)
	hpriv->port_clks = devm_kzalloc(&pdev->dev,
					sizeof(struct clk *) * n_ports,
					GFP_KERNEL);
	if (!hpriv->port_clks)
		return -ENOMEM;
#endif
	host->private_data = hpriv;
	hpriv->n_ports = n_ports;
	hpriv->board_idx = chip_soc;
@@ -4066,9 +4077,17 @@ static int mv_platform_probe(struct platform_device *pdev)
#if defined(CONFIG_HAVE_CLK)
	hpriv->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(hpriv->clk))
		dev_notice(&pdev->dev, "cannot get clkdev\n");
		dev_notice(&pdev->dev, "cannot get optional clkdev\n");
	else
		clk_enable(hpriv->clk);
		clk_prepare_enable(hpriv->clk);

	for (port = 0; port < n_ports; port++) {
		char port_number[16];
		sprintf(port_number, "%d", port);
		hpriv->port_clks[port] = clk_get(&pdev->dev, port_number);
		if (!IS_ERR(hpriv->port_clks[port]))
			clk_prepare_enable(hpriv->port_clks[port]);
	}
#endif

	/*
@@ -4098,9 +4117,15 @@ static int mv_platform_probe(struct platform_device *pdev)
err:
#if defined(CONFIG_HAVE_CLK)
	if (!IS_ERR(hpriv->clk)) {
		clk_disable(hpriv->clk);
		clk_disable_unprepare(hpriv->clk);
		clk_put(hpriv->clk);
	}
	for (port = 0; port < n_ports; port++) {
		if (!IS_ERR(hpriv->port_clks[port])) {
			clk_disable_unprepare(hpriv->port_clks[port]);
			clk_put(hpriv->port_clks[port]);
		}
	}
#endif

	return rc;
@@ -4119,14 +4144,21 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
	struct ata_host *host = platform_get_drvdata(pdev);
#if defined(CONFIG_HAVE_CLK)
	struct mv_host_priv *hpriv = host->private_data;
	int port;
#endif
	ata_host_detach(host);

#if defined(CONFIG_HAVE_CLK)
	if (!IS_ERR(hpriv->clk)) {
		clk_disable(hpriv->clk);
		clk_disable_unprepare(hpriv->clk);
		clk_put(hpriv->clk);
	}
	for (port = 0; port < host->n_ports; port++) {
		if (!IS_ERR(hpriv->port_clks[port])) {
			clk_disable_unprepare(hpriv->port_clks[port]);
			clk_put(hpriv->port_clks[port]);
		}
	}
#endif
	return 0;
}