* [RFC 0/2] mpc5200: eliminate direct manipulation of shared registers from SPI driver
@ 2008-01-07 19:03 Grant Likely
2008-01-07 19:03 ` [RFC 1/2] mpc5200: Add common clock setting routine mpc52xx_set_psc_clkdiv() Grant Likely
2008-01-07 19:07 ` [RFC 2/2] mpc52xx_psc_spi device driver must not touch port_config and cdm Grant Likely
0 siblings, 2 replies; 5+ messages in thread
From: Grant Likely @ 2008-01-07 19:03 UTC (permalink / raw)
To: dragos.carp, linuxppc-dev
The mpc5200 PSC SPI driver driver directly manipulates the port_config
and the CDM registers on the mpc5200 which it should not do. port_config
should only be manipulated from within the board specific platform code
and the CDM registers are shared between multiple devices.
This patch eliminates the port_config manipulations and adds a common
routine for adjusting CDM settings. Boards using the SPI driver will
need to add the required port_config changes to either the boot firmware
or the platform code.
If there are no objections, I plan to ask Paulus to merge these in the
next couple of days.
Cheers,
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC 1/2] mpc5200: Add common clock setting routine mpc52xx_set_psc_clkdiv()
2008-01-07 19:03 [RFC 0/2] mpc5200: eliminate direct manipulation of shared registers from SPI driver Grant Likely
@ 2008-01-07 19:03 ` Grant Likely
2008-01-08 1:04 ` Stephen Rothwell
2008-01-07 19:07 ` [RFC 2/2] mpc52xx_psc_spi device driver must not touch port_config and cdm Grant Likely
1 sibling, 1 reply; 5+ messages in thread
From: Grant Likely @ 2008-01-07 19:03 UTC (permalink / raw)
To: dragos.carp, linuxppc-dev
From: Grant Likely <grant.likely@secretlab.ca>
PSC drivers should not access the CDM registers directly. Instead provide
a common routine for setting the PSC clock parameters with the required
locking.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/platforms/52xx/efika.c | 3 +
arch/powerpc/platforms/52xx/lite5200.c | 10 +--
arch/powerpc/platforms/52xx/mpc5200_simple.c | 6 +-
arch/powerpc/platforms/52xx/mpc52xx_common.c | 91 +++++++++++++++++++++-----
arch/ppc/syslib/mpc52xx_setup.c | 36 ++++++++++
include/asm-powerpc/mpc52xx.h | 13 ++--
6 files changed, 130 insertions(+), 29 deletions(-)
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index a0da70c..a2068fa 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -180,6 +180,9 @@ static void __init efika_setup_arch(void)
{
rtas_initialize();
+ /* Map important registers from the internal memory map */
+ mpc52xx_map_common_devices();
+
efika_pcisetup();
#ifdef CONFIG_PM
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index f8ba5f2..42e87b6 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -150,15 +150,15 @@ static void __init lite5200_setup_arch(void)
if (ppc_md.progress)
ppc_md.progress("lite5200_setup_arch()", 0);
- /* Fix things that firmware should have done. */
- lite5200_fix_clock_config();
- lite5200_fix_port_config();
+ /* Map important registers from the internal memory map */
+ mpc52xx_map_common_devices();
/* Some mpc5200 & mpc5200b related configuration */
mpc5200_setup_xlb_arbiter();
- /* Map wdt for mpc52xx_restart() */
- mpc52xx_map_wdt();
+ /* Fix things that firmware should have done. */
+ lite5200_fix_clock_config();
+ lite5200_fix_port_config();
#ifdef CONFIG_PM
mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index 754aa93..c48b82b 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -39,12 +39,12 @@ static void __init mpc5200_simple_setup_arch(void)
if (ppc_md.progress)
ppc_md.progress("mpc5200_simple_setup_arch()", 0);
+ /* Map important registers from the internal memory map */
+ mpc52xx_map_common_devices();
+
/* Some mpc5200 & mpc5200b related configuration */
mpc5200_setup_xlb_arbiter();
- /* Map wdt for mpc52xx_restart() */
- mpc52xx_map_wdt();
-
mpc52xx_setup_pci();
}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 59346e3..67eba48 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -13,6 +13,7 @@
#undef DEBUG
#include <linux/kernel.h>
+#include <linux/spinlock.h>
#include <linux/of_platform.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -24,7 +25,9 @@
* from interrupt context while node mapping (which calls ioremap())
* cannot be used at such point.
*/
-static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL;
+static spinlock_t mpc52xx_lock = SPIN_LOCK_UNLOCKED;
+static struct mpc52xx_gpt __iomem *mpc52xx_wdt;
+static struct mpc52xx_cdm __iomem *mpc52xx_cdm;
/**
* mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
@@ -93,32 +96,43 @@ mpc5200_setup_xlb_arbiter(void)
iounmap(xlb);
}
-static struct of_device_id __init mpc52xx_ids[] = {
- { .compatible = "fsl,mpc5200-immr", },
- { .compatible = "fsl,lpb", },
-
- /* depreciated matches; shouldn't be used in new device trees */
- { .type = "builtin", .compatible = "mpc5200", }, /* efika */
- { .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
- {}
-};
-
+/**
+ * mpc52xx_declare_of_platform_devices: register internal devices and children
+ * of the localplus bus to the of_platform
+ * bus.
+ */
void __init
mpc52xx_declare_of_platform_devices(void)
{
+ const static struct of_device_id mpc52xx_bus_ids[] = {
+ { .compatible = "fsl,mpc5200-immr", },
+ { .compatible = "fsl,lpb", },
+ { .type = "builtin", .compatible = "mpc5200", }, /* efika */
+ { .type = "soc", .compatible = "mpc5200", }, /* old */
+ {}
+ };
+
/* Find every child of the SOC node and add it to of_platform */
- if (of_platform_bus_probe(NULL, mpc52xx_ids, NULL))
+ if (of_platform_bus_probe(NULL, mpc52xx_bus_ids, NULL))
printk(KERN_ERR __FILE__ ": "
"Error while probing of_platform bus\n");
}
+/**
+ * mpc52xx_map_common_devices: iomap devices required by common code
+ */
void __init
-mpc52xx_map_wdt(void)
+mpc52xx_map_common_devices(void)
{
struct device_node *np;
- struct of_device_id gpt_ids[] = {
+ const static struct of_device_id gpt_ids[] = {
{ .compatible = "fsl,mpc5200-gpt", },
- { .compatible = "mpc5200-gpt", },
+ { .compatible = "mpc5200-gpt", }, /* old */
+ {}
+ };
+ const static struct of_device_id cdm_ids[] = {
+ { .compatible = "fsl,mpc5200-cdm", },
+ { .compatible = "mpc5200-cdm", }, /* old */
{}
};
@@ -131,11 +145,56 @@ mpc52xx_map_wdt(void)
of_get_property(np, "has-wdt", NULL)) {
mpc52xx_wdt = of_iomap(np, 0);
of_node_put(np);
- return;
+ break;
}
}
+
+ /* Clock Distribution Module, used by PSC clock setting function */
+ np = of_find_matching_node(NULL, cdm_ids);
+ mpc52xx_cdm = of_iomap(np, 0);
+ of_node_put(np);
+}
+
+/**
+ * mpc52xx_set_psc_clkdiv: Set clock divider in the CDM for PSC ports
+ *
+ * @psc_id: id of psc port; must be 1,2,3 or 6
+ * @clkdiv: clock divider value to put into CDM PSC register.
+ */
+int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
+{
+ unsigned long flags;
+ u16 __iomem *reg;
+ u32 val;
+ u32 mask;
+ u32 mclken_div;
+
+ if (!mpc52xx_cdm)
+ return -ENODEV;
+
+ mclken_div = 0x8000 | (clkdiv & 0x1FF);
+ switch (psc_id) {
+ case 1: reg = &mpc52xx_cdm->mclken_div_psc1; mask = 0x20; break;
+ case 2: reg = &mpc52xx_cdm->mclken_div_psc2; mask = 0x40; break;
+ case 3: reg = &mpc52xx_cdm->mclken_div_psc3; mask = 0x80; break;
+ case 6: reg = &mpc52xx_cdm->mclken_div_psc6; mask = 0x10; break;
+ default:
+ return -ENODEV;
+ }
+
+ /* Set the rate and enable the clock */
+ spin_lock_irqsave(&mpc52xx_lock, flags);
+ out_be16(reg, mclken_div);
+ val = in_be32(&mpc52xx_cdm->clk_enables);
+ out_be32(&mpc52xx_cdm->clk_enables, val | mask);
+ spin_unlock_irqrestore(&mpc52xx_lock, flags);
+
+ return 0;
}
+/**
+ * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
+ */
void
mpc52xx_restart(char *cmd)
{
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index ecfa2c0..791fc8d 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -16,6 +16,7 @@
*/
+#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/time.h>
#include <asm/mpc52xx.h>
@@ -275,3 +276,38 @@ int mpc52xx_match_psc_function(int psc_idx, const char *func)
return 0;
}
+
+int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
+{
+ static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+ struct mpc52xx_cdm __iomem *cdm;
+ unsigned long flags;
+ u16 mclken_div;
+ u16 __iomem *reg;
+ u32 mask;
+
+ cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
+ if (!cdm) {
+ printk(KERN_ERR __FILE__ ": Error mapping CDM\n");
+ return -ENODEV
+ }
+
+ mclken_div = 0x8000 | (clkdiv & 0x1FF);
+ switch (psc_id) {
+ case 1: reg = &cdm->mclken_div_psc1; mask = 0x20; break;
+ case 2: reg = &cdm->mclken_div_psc2; mask = 0x40; break;
+ case 3: reg = &cdm->mclken_div_psc3; mask = 0x80; break;
+ case 6: reg = &cdm->mclken_div_psc6; mask = 0x10; break;
+ default:
+ return -ENODEV;
+ }
+
+ /* Set the rate and enable the clock */
+ spin_lock_irqsave(&lock, flags);
+ out_be16(reg, mclken_div);
+ out_be32(&cdm->clk_enables, in_be32(&cdm->clk_enables) | mask);
+ spin_unlock_irqrestore(&lock, flags);
+
+ iounmap(cdm);
+ return 0;
+}
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 1c48c6d..c7a0710 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -248,13 +248,19 @@ struct mpc52xx_cdm {
#ifndef __ASSEMBLY__
+/* mpc52xx_common.c */
extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node);
-extern void mpc5200_setup_xlb_arbiter(void);
-extern void mpc52xx_declare_of_platform_devices(void);
+extern void __init mpc5200_setup_xlb_arbiter(void);
+extern void __init mpc52xx_declare_of_platform_devices(void);
+extern void __init mpc52xx_map_common_devices(void);
+extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
+extern void mpc52xx_restart(char *cmd);
+/* mpc52xx_pic.c */
extern void mpc52xx_init_irq(void);
extern unsigned int mpc52xx_get_irq(void);
+/* mpc52xx_pci.c */
#ifdef CONFIG_PCI
extern int __init mpc52xx_add_bridge(struct device_node *node);
extern void __init mpc52xx_setup_pci(void);
@@ -262,9 +268,6 @@ extern void __init mpc52xx_setup_pci(void);
static inline void mpc52xx_setup_pci(void) { }
#endif
-extern void __init mpc52xx_map_wdt(void);
-extern void mpc52xx_restart(char *cmd);
-
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_PM
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC 2/2] mpc52xx_psc_spi device driver must not touch port_config and cdm
2008-01-07 19:03 [RFC 0/2] mpc5200: eliminate direct manipulation of shared registers from SPI driver Grant Likely
2008-01-07 19:03 ` [RFC 1/2] mpc5200: Add common clock setting routine mpc52xx_set_psc_clkdiv() Grant Likely
@ 2008-01-07 19:07 ` Grant Likely
2008-01-10 14:03 ` Dragos Carp
1 sibling, 1 reply; 5+ messages in thread
From: Grant Likely @ 2008-01-07 19:07 UTC (permalink / raw)
To: dragos.carp, linuxppc-dev
From: Grant Likely <grant.likely@secretlab.ca>
It is dangerous for an mpc52xx device driver to modify the port_config
register. If the driver is probed incorrectly, it will change the pin
IO configuration in ways which may not be compatible with the board.
port_config should be set up by the bootloader, or failing that, in
the platform setup code in arch/powerpc/platforms/52xx.
Also, modifying CDM registers directly can cause a race condition with
other drivers. Instead call a common routine to modify CDM settings.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/spi/mpc52xx_psc_spi.c | 77 +----------------------------------------
1 files changed, 2 insertions(+), 75 deletions(-)
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index a3ebc63..253ed56 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -330,80 +330,13 @@ static void mpc52xx_psc_spi_cleanup(struct spi_device *spi)
static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
{
- struct device_node *np;
- struct mpc52xx_cdm __iomem *cdm;
- struct mpc52xx_gpio __iomem *gpio;
struct mpc52xx_psc __iomem *psc = mps->psc;
- u32 ul;
u32 mclken_div;
int ret = 0;
-#if defined(CONFIG_PPC_MERGE)
- np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm");
- cdm = of_iomap(np, 0);
- of_node_put(np);
- np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio");
- gpio = of_iomap(np, 0);
- of_node_put(np);
-#else
- cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
- gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
-#endif
- if (!cdm || !gpio) {
- printk(KERN_ERR "Error mapping CDM/GPIO\n");
- ret = -EFAULT;
- goto unmap_regs;
- }
-
/* default sysclk is 512MHz */
- mclken_div = 0x8000 |
- (((mps->sysclk ? mps->sysclk : 512000000) / MCLK) & 0x1FF);
-
- switch (psc_id) {
- case 1:
- ul = in_be32(&gpio->port_config);
- ul &= 0xFFFFFFF8;
- ul |= 0x00000006;
- out_be32(&gpio->port_config, ul);
- out_be16(&cdm->mclken_div_psc1, mclken_div);
- ul = in_be32(&cdm->clk_enables);
- ul |= 0x00000020;
- out_be32(&cdm->clk_enables, ul);
- break;
- case 2:
- ul = in_be32(&gpio->port_config);
- ul &= 0xFFFFFF8F;
- ul |= 0x00000060;
- out_be32(&gpio->port_config, ul);
- out_be16(&cdm->mclken_div_psc2, mclken_div);
- ul = in_be32(&cdm->clk_enables);
- ul |= 0x00000040;
- out_be32(&cdm->clk_enables, ul);
- break;
- case 3:
- ul = in_be32(&gpio->port_config);
- ul &= 0xFFFFF0FF;
- ul |= 0x00000600;
- out_be32(&gpio->port_config, ul);
- out_be16(&cdm->mclken_div_psc3, mclken_div);
- ul = in_be32(&cdm->clk_enables);
- ul |= 0x00000080;
- out_be32(&cdm->clk_enables, ul);
- break;
- case 6:
- ul = in_be32(&gpio->port_config);
- ul &= 0xFF8FFFFF;
- ul |= 0x00700000;
- out_be32(&gpio->port_config, ul);
- out_be16(&cdm->mclken_div_psc6, mclken_div);
- ul = in_be32(&cdm->clk_enables);
- ul |= 0x00000010;
- out_be32(&cdm->clk_enables, ul);
- break;
- default:
- ret = -EINVAL;
- goto unmap_regs;
- }
+ mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK;
+ mpc52xx_set_psc_clkdiv(psc_id, mclken_div);
/* Reset the PSC into a known state */
out_8(&psc->command, MPC52xx_PSC_RST_RX);
@@ -427,12 +360,6 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
mps->bits_per_word = 8;
-unmap_regs:
- if (cdm)
- iounmap(cdm);
- if (gpio)
- iounmap(gpio);
-
return ret;
}
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [RFC 1/2] mpc5200: Add common clock setting routine mpc52xx_set_psc_clkdiv()
2008-01-07 19:03 ` [RFC 1/2] mpc5200: Add common clock setting routine mpc52xx_set_psc_clkdiv() Grant Likely
@ 2008-01-08 1:04 ` Stephen Rothwell
0 siblings, 0 replies; 5+ messages in thread
From: Stephen Rothwell @ 2008-01-08 1:04 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, dragos.carp
[-- Attachment #1: Type: text/plain, Size: 1247 bytes --]
On Mon, 07 Jan 2008 12:03:59 -0700 Grant Likely <grant.likely@secretlab.ca> wrote:
>
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
>
> -static struct of_device_id __init mpc52xx_ids[] = {
Why not just leave this here and mark in __initdata?
> +/**
> + * mpc52xx_declare_of_platform_devices: register internal devices and children
> + * of the localplus bus to the of_platform
> + * bus.
> + */
> void __init
> mpc52xx_declare_of_platform_devices(void)
> {
> + const static struct of_device_id mpc52xx_bus_ids[] = {
Or just mark it __initdata instead of const?
> + { .compatible = "fsl,mpc5200-immr", },
> + { .compatible = "fsl,lpb", },
> + { .type = "builtin", .compatible = "mpc5200", }, /* efika */
> + { .type = "soc", .compatible = "mpc5200", }, /* old */
And you lost the comment about the last two being deprecated mates.
> +mpc52xx_map_common_devices(void)
> {
> struct device_node *np;
> - struct of_device_id gpt_ids[] = {
> + const static struct of_device_id gpt_ids[] = {
Again __initdata?
> + const static struct of_device_id cdm_ids[] = {
And again?
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC 2/2] mpc52xx_psc_spi device driver must not touch port_config and cdm
2008-01-07 19:07 ` [RFC 2/2] mpc52xx_psc_spi device driver must not touch port_config and cdm Grant Likely
@ 2008-01-10 14:03 ` Dragos Carp
0 siblings, 0 replies; 5+ messages in thread
From: Dragos Carp @ 2008-01-10 14:03 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
Acked-by: Dragos Carp <dragos.carp@toptica.com>
On Mon, 2008-01-07 at 12:07 -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> It is dangerous for an mpc52xx device driver to modify the port_config
> register. If the driver is probed incorrectly, it will change the pin
> IO configuration in ways which may not be compatible with the board.
> port_config should be set up by the bootloader, or failing that, in
> the platform setup code in arch/powerpc/platforms/52xx.
>
> Also, modifying CDM registers directly can cause a race condition with
> other drivers. Instead call a common routine to modify CDM settings.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> drivers/spi/mpc52xx_psc_spi.c | 77 +----------------------------------------
> 1 files changed, 2 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
> index a3ebc63..253ed56 100644
> --- a/drivers/spi/mpc52xx_psc_spi.c
> +++ b/drivers/spi/mpc52xx_psc_spi.c
> @@ -330,80 +330,13 @@ static void mpc52xx_psc_spi_cleanup(struct spi_device *spi)
>
> static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
> {
> - struct device_node *np;
> - struct mpc52xx_cdm __iomem *cdm;
> - struct mpc52xx_gpio __iomem *gpio;
> struct mpc52xx_psc __iomem *psc = mps->psc;
> - u32 ul;
> u32 mclken_div;
> int ret = 0;
>
> -#if defined(CONFIG_PPC_MERGE)
> - np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm");
> - cdm = of_iomap(np, 0);
> - of_node_put(np);
> - np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio");
> - gpio = of_iomap(np, 0);
> - of_node_put(np);
> -#else
> - cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
> - gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
> -#endif
> - if (!cdm || !gpio) {
> - printk(KERN_ERR "Error mapping CDM/GPIO\n");
> - ret = -EFAULT;
> - goto unmap_regs;
> - }
> -
> /* default sysclk is 512MHz */
> - mclken_div = 0x8000 |
> - (((mps->sysclk ? mps->sysclk : 512000000) / MCLK) & 0x1FF);
> -
> - switch (psc_id) {
> - case 1:
> - ul = in_be32(&gpio->port_config);
> - ul &= 0xFFFFFFF8;
> - ul |= 0x00000006;
> - out_be32(&gpio->port_config, ul);
> - out_be16(&cdm->mclken_div_psc1, mclken_div);
> - ul = in_be32(&cdm->clk_enables);
> - ul |= 0x00000020;
> - out_be32(&cdm->clk_enables, ul);
> - break;
> - case 2:
> - ul = in_be32(&gpio->port_config);
> - ul &= 0xFFFFFF8F;
> - ul |= 0x00000060;
> - out_be32(&gpio->port_config, ul);
> - out_be16(&cdm->mclken_div_psc2, mclken_div);
> - ul = in_be32(&cdm->clk_enables);
> - ul |= 0x00000040;
> - out_be32(&cdm->clk_enables, ul);
> - break;
> - case 3:
> - ul = in_be32(&gpio->port_config);
> - ul &= 0xFFFFF0FF;
> - ul |= 0x00000600;
> - out_be32(&gpio->port_config, ul);
> - out_be16(&cdm->mclken_div_psc3, mclken_div);
> - ul = in_be32(&cdm->clk_enables);
> - ul |= 0x00000080;
> - out_be32(&cdm->clk_enables, ul);
> - break;
> - case 6:
> - ul = in_be32(&gpio->port_config);
> - ul &= 0xFF8FFFFF;
> - ul |= 0x00700000;
> - out_be32(&gpio->port_config, ul);
> - out_be16(&cdm->mclken_div_psc6, mclken_div);
> - ul = in_be32(&cdm->clk_enables);
> - ul |= 0x00000010;
> - out_be32(&cdm->clk_enables, ul);
> - break;
> - default:
> - ret = -EINVAL;
> - goto unmap_regs;
> - }
> + mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK;
> + mpc52xx_set_psc_clkdiv(psc_id, mclken_div);
>
> /* Reset the PSC into a known state */
> out_8(&psc->command, MPC52xx_PSC_RST_RX);
> @@ -427,12 +360,6 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
>
> mps->bits_per_word = 8;
>
> -unmap_regs:
> - if (cdm)
> - iounmap(cdm);
> - if (gpio)
> - iounmap(gpio);
> -
> return ret;
> }
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-01-10 14:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-07 19:03 [RFC 0/2] mpc5200: eliminate direct manipulation of shared registers from SPI driver Grant Likely
2008-01-07 19:03 ` [RFC 1/2] mpc5200: Add common clock setting routine mpc52xx_set_psc_clkdiv() Grant Likely
2008-01-08 1:04 ` Stephen Rothwell
2008-01-07 19:07 ` [RFC 2/2] mpc52xx_psc_spi device driver must not touch port_config and cdm Grant Likely
2008-01-10 14:03 ` Dragos Carp
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).