Commit 4574b886 authored by Andrew Lunn's avatar Andrew Lunn Committed by Mike Turquette

ARM: Orion: SPI: Add clk/clkdev support.

Remove now redundant tclk from SPI platform data. This makes the platform
data empty, so remove it.
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 2f129bf4
...@@ -76,6 +76,8 @@ static void __init clk_init(void) ...@@ -76,6 +76,8 @@ static void __init clk_init(void)
{ {
tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
get_tclk()); get_tclk());
orion_clkdev_init(tclk);
} }
/***************************************************************************** /*****************************************************************************
...@@ -162,12 +164,12 @@ void __init dove_uart3_init(void) ...@@ -162,12 +164,12 @@ void __init dove_uart3_init(void)
****************************************************************************/ ****************************************************************************/
void __init dove_spi0_init(void) void __init dove_spi0_init(void)
{ {
orion_spi_init(DOVE_SPI0_PHYS_BASE, get_tclk()); orion_spi_init(DOVE_SPI0_PHYS_BASE);
} }
void __init dove_spi1_init(void) void __init dove_spi1_init(void)
{ {
orion_spi_1_init(DOVE_SPI1_PHYS_BASE, get_tclk()); orion_spi_1_init(DOVE_SPI1_PHYS_BASE);
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/spi/flash.h> #include <linux/spi/flash.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/spi/flash.h> #include <linux/spi/flash.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
......
...@@ -86,10 +86,12 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) ...@@ -86,10 +86,12 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx)
void __init kirkwood_clk_init(void) void __init kirkwood_clk_init(void)
{ {
struct clk *runit;
tclk = clk_register_fixed_rate(NULL, "tclk", NULL, tclk = clk_register_fixed_rate(NULL, "tclk", NULL,
CLK_IS_ROOT, kirkwood_tclk); CLK_IS_ROOT, kirkwood_tclk);
kirkwood_register_gate("runit", CGC_BIT_RUNIT); runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT);
kirkwood_register_gate("ge0", CGC_BIT_GE0); kirkwood_register_gate("ge0", CGC_BIT_GE0);
kirkwood_register_gate("ge1", CGC_BIT_GE1); kirkwood_register_gate("ge1", CGC_BIT_GE1);
kirkwood_register_gate("sata0", CGC_BIT_SATA0); kirkwood_register_gate("sata0", CGC_BIT_SATA0);
...@@ -104,6 +106,10 @@ void __init kirkwood_clk_init(void) ...@@ -104,6 +106,10 @@ void __init kirkwood_clk_init(void)
kirkwood_register_gate("audio", CGC_BIT_AUDIO); kirkwood_register_gate("audio", CGC_BIT_AUDIO);
kirkwood_register_gate("tdm", CGC_BIT_TDM); kirkwood_register_gate("tdm", CGC_BIT_TDM);
kirkwood_register_gate("tsu", CGC_BIT_TSU); kirkwood_register_gate("tsu", CGC_BIT_TSU);
/* clkdev entries, mapping clks to devices */
orion_clkdev_add(NULL, "orion_spi.0", runit);
orion_clkdev_add(NULL, "orion_spi.1", runit);
} }
/***************************************************************************** /*****************************************************************************
...@@ -270,7 +276,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) ...@@ -270,7 +276,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
void __init kirkwood_spi_init() void __init kirkwood_spi_init()
{ {
kirkwood_clk_ctrl |= CGC_RUNIT; kirkwood_clk_ctrl |= CGC_RUNIT;
orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk); orion_spi_init(SPI_PHYS_BASE);
} }
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/gpio_keys.h> #include <linux/gpio_keys.h>
#include <linux/spi/flash.h> #include <linux/spi/flash.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <net/dsa.h> #include <net/dsa.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/spi/flash.h> #include <linux/spi/flash.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <mach/kirkwood.h> #include <mach/kirkwood.h>
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/spi/flash.h> #include <linux/spi/flash.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h> #include <linux/ata_platform.h>
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/spi/flash.h> #include <linux/spi/flash.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <mach/kirkwood.h> #include <mach/kirkwood.h>
#include "common.h" #include "common.h"
......
...@@ -175,6 +175,8 @@ static void __init clk_init(void) ...@@ -175,6 +175,8 @@ static void __init clk_init(void)
{ {
tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
get_tclk()); get_tclk());
orion_clkdev_init(tclk);
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -79,6 +79,8 @@ static void __init clk_init(void) ...@@ -79,6 +79,8 @@ static void __init clk_init(void)
{ {
tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
orion5x_tclk); orion5x_tclk);
orion_clkdev_init(tclk);
} }
/***************************************************************************** /*****************************************************************************
...@@ -144,7 +146,7 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) ...@@ -144,7 +146,7 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
****************************************************************************/ ****************************************************************************/
void __init orion5x_spi_init() void __init orion5x_spi_init()
{ {
orion_spi_init(SPI_PHYS_BASE, orion5x_tclk); orion_spi_init(SPI_PHYS_BASE);
} }
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/spi/flash.h> #include <linux/spi/flash.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <net/dsa.h> #include <net/dsa.h>
......
...@@ -19,12 +19,32 @@ ...@@ -19,12 +19,32 @@
#include <linux/mv643xx_eth.h> #include <linux/mv643xx_eth.h>
#include <linux/mv643xx_i2c.h> #include <linux/mv643xx_i2c.h>
#include <net/dsa.h> #include <net/dsa.h>
#include <linux/spi/orion_spi.h>
#include <plat/orion_wdt.h> #include <plat/orion_wdt.h>
#include <plat/mv_xor.h> #include <plat/mv_xor.h>
#include <plat/ehci-orion.h> #include <plat/ehci-orion.h>
#include <mach/bridge-regs.h> #include <mach/bridge-regs.h>
/* Create a clkdev entry for a given device/clk */
void __init orion_clkdev_add(const char *con_id, const char *dev_id,
struct clk *clk)
{
struct clk_lookup *cl;
cl = clkdev_alloc(clk, con_id, dev_id);
if (cl)
clkdev_add(cl);
}
/* Create clkdev entries for all orion platforms except kirkwood.
Kirkwood has gated clocks for some of its peripherals, so creates
its own clkdev entries. For all the other orion devices, create
clkdev entries to the tclk. */
void __init orion_clkdev_init(struct clk *tclk)
{
orion_clkdev_add(NULL, "orion_spi.0", tclk);
orion_clkdev_add(NULL, "orion_spi.1", tclk);
}
/* Fill in the resources structure and link it into the platform /* Fill in the resources structure and link it into the platform
device structure. There is always a memory region, and nearly device structure. There is always a memory region, and nearly
always an interrupt.*/ always an interrupt.*/
...@@ -523,44 +543,32 @@ void __init orion_i2c_1_init(unsigned long mapbase, ...@@ -523,44 +543,32 @@ void __init orion_i2c_1_init(unsigned long mapbase,
/***************************************************************************** /*****************************************************************************
* SPI * SPI
****************************************************************************/ ****************************************************************************/
static struct orion_spi_info orion_spi_plat_data;
static struct resource orion_spi_resources; static struct resource orion_spi_resources;
static struct platform_device orion_spi = { static struct platform_device orion_spi = {
.name = "orion_spi", .name = "orion_spi",
.id = 0, .id = 0,
.dev = {
.platform_data = &orion_spi_plat_data,
},
}; };
static struct orion_spi_info orion_spi_1_plat_data;
static struct resource orion_spi_1_resources; static struct resource orion_spi_1_resources;
static struct platform_device orion_spi_1 = { static struct platform_device orion_spi_1 = {
.name = "orion_spi", .name = "orion_spi",
.id = 1, .id = 1,
.dev = {
.platform_data = &orion_spi_1_plat_data,
},
}; };
/* Note: The SPI silicon core does have interrupts. However the /* Note: The SPI silicon core does have interrupts. However the
* current Linux software driver does not use interrupts. */ * current Linux software driver does not use interrupts. */
void __init orion_spi_init(unsigned long mapbase, void __init orion_spi_init(unsigned long mapbase)
unsigned long tclk)
{ {
orion_spi_plat_data.tclk = tclk;
fill_resources(&orion_spi, &orion_spi_resources, fill_resources(&orion_spi, &orion_spi_resources,
mapbase, SZ_512 - 1, NO_IRQ); mapbase, SZ_512 - 1, NO_IRQ);
platform_device_register(&orion_spi); platform_device_register(&orion_spi);
} }
void __init orion_spi_1_init(unsigned long mapbase, void __init orion_spi_1_init(unsigned long mapbase)
unsigned long tclk)
{ {
orion_spi_1_plat_data.tclk = tclk;
fill_resources(&orion_spi_1, &orion_spi_1_resources, fill_resources(&orion_spi_1, &orion_spi_1_resources,
mapbase, SZ_512 - 1, NO_IRQ); mapbase, SZ_512 - 1, NO_IRQ);
platform_device_register(&orion_spi_1); platform_device_register(&orion_spi_1);
......
...@@ -70,11 +70,9 @@ void __init orion_i2c_1_init(unsigned long mapbase, ...@@ -70,11 +70,9 @@ void __init orion_i2c_1_init(unsigned long mapbase,
unsigned long irq, unsigned long irq,
unsigned long freq_m); unsigned long freq_m);
void __init orion_spi_init(unsigned long mapbase, void __init orion_spi_init(unsigned long mapbase);
unsigned long tclk);
void __init orion_spi_1_init(unsigned long mapbase, void __init orion_spi_1_init(unsigned long mapbase);
unsigned long tclk);
void __init orion_wdt_init(unsigned long tclk); void __init orion_wdt_init(unsigned long tclk);
...@@ -106,4 +104,9 @@ void __init orion_crypto_init(unsigned long mapbase, ...@@ -106,4 +104,9 @@ void __init orion_crypto_init(unsigned long mapbase,
unsigned long srambase, unsigned long srambase,
unsigned long sram_size, unsigned long sram_size,
unsigned long irq); unsigned long irq);
void __init orion_clkdev_add(const char *con_id, const char *dev_id,
struct clk *clk);
void __init orion_clkdev_init(struct clk *tclk);
#endif #endif
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/orion_spi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/clk.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#define DRIVER_NAME "orion_spi" #define DRIVER_NAME "orion_spi"
...@@ -46,6 +46,7 @@ struct orion_spi { ...@@ -46,6 +46,7 @@ struct orion_spi {
unsigned int max_speed; unsigned int max_speed;
unsigned int min_speed; unsigned int min_speed;
struct orion_spi_info *spi_info; struct orion_spi_info *spi_info;
struct clk *clk;
}; };
static struct workqueue_struct *orion_spi_wq; static struct workqueue_struct *orion_spi_wq;
...@@ -104,7 +105,7 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed) ...@@ -104,7 +105,7 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
orion_spi = spi_master_get_devdata(spi->master); orion_spi = spi_master_get_devdata(spi->master);
tclk_hz = orion_spi->spi_info->tclk; tclk_hz = clk_get_rate(orion_spi->clk);
/* /*
* the supported rates are: 4,6,8...30 * the supported rates are: 4,6,8...30
...@@ -450,6 +451,7 @@ static int __init orion_spi_probe(struct platform_device *pdev) ...@@ -450,6 +451,7 @@ static int __init orion_spi_probe(struct platform_device *pdev)
struct orion_spi *spi; struct orion_spi *spi;
struct resource *r; struct resource *r;
struct orion_spi_info *spi_info; struct orion_spi_info *spi_info;
unsigned long tclk_hz;
int status = 0; int status = 0;
spi_info = pdev->dev.platform_data; spi_info = pdev->dev.platform_data;
...@@ -476,19 +478,28 @@ static int __init orion_spi_probe(struct platform_device *pdev) ...@@ -476,19 +478,28 @@ static int __init orion_spi_probe(struct platform_device *pdev)
spi->master = master; spi->master = master;
spi->spi_info = spi_info; spi->spi_info = spi_info;
spi->max_speed = DIV_ROUND_UP(spi_info->tclk, 4); spi->clk = clk_get(&pdev->dev, NULL);
spi->min_speed = DIV_ROUND_UP(spi_info->tclk, 30); if (IS_ERR(spi->clk)) {
status = PTR_ERR(spi->clk);
goto out;
}
clk_prepare(spi->clk);
clk_enable(spi->clk);
tclk_hz = clk_get_rate(spi->clk);
spi->max_speed = DIV_ROUND_UP(tclk_hz, 4);
spi->min_speed = DIV_ROUND_UP(tclk_hz, 30);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) { if (r == NULL) {
status = -ENODEV; status = -ENODEV;
goto out; goto out_rel_clk;
} }
if (!request_mem_region(r->start, resource_size(r), if (!request_mem_region(r->start, resource_size(r),
dev_name(&pdev->dev))) { dev_name(&pdev->dev))) {
status = -EBUSY; status = -EBUSY;
goto out; goto out_rel_clk;
} }
spi->base = ioremap(r->start, SZ_1K); spi->base = ioremap(r->start, SZ_1K);
...@@ -508,7 +519,9 @@ static int __init orion_spi_probe(struct platform_device *pdev) ...@@ -508,7 +519,9 @@ static int __init orion_spi_probe(struct platform_device *pdev)
out_rel_mem: out_rel_mem:
release_mem_region(r->start, resource_size(r)); release_mem_region(r->start, resource_size(r));
out_rel_clk:
clk_disable_unprepare(spi->clk);
clk_put(spi->clk);
out: out:
spi_master_put(master); spi_master_put(master);
return status; return status;
...@@ -526,6 +539,9 @@ static int __exit orion_spi_remove(struct platform_device *pdev) ...@@ -526,6 +539,9 @@ static int __exit orion_spi_remove(struct platform_device *pdev)
cancel_work_sync(&spi->work); cancel_work_sync(&spi->work);
clk_disable_unprepare(spi->clk);
clk_put(spi->clk);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(r->start, resource_size(r)); release_mem_region(r->start, resource_size(r));
......
/*
* orion_spi.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __LINUX_SPI_ORION_SPI_H
#define __LINUX_SPI_ORION_SPI_H
struct orion_spi_info {
u32 tclk; /* no <linux/clk.h> support yet */
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment