aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2008-01-25 00:25:31 -0500
committerGrant Likely <grant.likely@secretlab.ca>2008-01-26 17:32:19 -0500
commit4fb4c5582475452d3bf7c5072ef2d15ee06f7723 (patch)
tree9e75d2795deafb6601fb31c858874ebd554a4135
parentc8004a28186110657aa3e75135a6b96ebfa3e8f0 (diff)
[POWERPC] mpc52xx_psc_spi device driver must not touch port_config and cdm
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> Acked-by: Dragos Carp <dragos.carp@toptica.com>
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c77
1 files changed, 2 insertions, 75 deletions
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index a3ebc632a477..253ed5682a6d 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)
330 330
331static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) 331static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
332{ 332{
333 struct device_node *np;
334 struct mpc52xx_cdm __iomem *cdm;
335 struct mpc52xx_gpio __iomem *gpio;
336 struct mpc52xx_psc __iomem *psc = mps->psc; 333 struct mpc52xx_psc __iomem *psc = mps->psc;
337 u32 ul;
338 u32 mclken_div; 334 u32 mclken_div;
339 int ret = 0; 335 int ret = 0;
340 336
341#if defined(CONFIG_PPC_MERGE)
342 np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm");
343 cdm = of_iomap(np, 0);
344 of_node_put(np);
345 np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio");
346 gpio = of_iomap(np, 0);
347 of_node_put(np);
348#else
349 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
350 gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
351#endif
352 if (!cdm || !gpio) {
353 printk(KERN_ERR "Error mapping CDM/GPIO\n");
354 ret = -EFAULT;
355 goto unmap_regs;
356 }
357
358 /* default sysclk is 512MHz */ 337 /* default sysclk is 512MHz */
359 mclken_div = 0x8000 | 338 mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK;
360 (((mps->sysclk ? mps->sysclk : 512000000) / MCLK) & 0x1FF); 339 mpc52xx_set_psc_clkdiv(psc_id, mclken_div);
361
362 switch (psc_id) {
363 case 1:
364 ul = in_be32(&gpio->port_config);
365 ul &= 0xFFFFFFF8;
366 ul |= 0x00000006;
367 out_be32(&gpio->port_config, ul);
368 out_be16(&cdm->mclken_div_psc1, mclken_div);
369 ul = in_be32(&cdm->clk_enables);
370 ul |= 0x00000020;
371 out_be32(&cdm->clk_enables, ul);
372 break;
373 case 2:
374 ul = in_be32(&gpio->port_config);
375 ul &= 0xFFFFFF8F;
376 ul |= 0x00000060;
377 out_be32(&gpio->port_config, ul);
378 out_be16(&cdm->mclken_div_psc2, mclken_div);
379 ul = in_be32(&cdm->clk_enables);
380 ul |= 0x00000040;
381 out_be32(&cdm->clk_enables, ul);
382 break;
383 case 3:
384 ul = in_be32(&gpio->port_config);
385 ul &= 0xFFFFF0FF;
386 ul |= 0x00000600;
387 out_be32(&gpio->port_config, ul);
388 out_be16(&cdm->mclken_div_psc3, mclken_div);
389 ul = in_be32(&cdm->clk_enables);
390 ul |= 0x00000080;
391 out_be32(&cdm->clk_enables, ul);
392 break;
393 case 6:
394 ul = in_be32(&gpio->port_config);
395 ul &= 0xFF8FFFFF;
396 ul |= 0x00700000;
397 out_be32(&gpio->port_config, ul);
398 out_be16(&cdm->mclken_div_psc6, mclken_div);
399 ul = in_be32(&cdm->clk_enables);
400 ul |= 0x00000010;
401 out_be32(&cdm->clk_enables, ul);
402 break;
403 default:
404 ret = -EINVAL;
405 goto unmap_regs;
406 }
407 340
408 /* Reset the PSC into a known state */ 341 /* Reset the PSC into a known state */
409 out_8(&psc->command, MPC52xx_PSC_RST_RX); 342 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)
427 360
428 mps->bits_per_word = 8; 361 mps->bits_per_word = 8;
429 362
430unmap_regs:
431 if (cdm)
432 iounmap(cdm);
433 if (gpio)
434 iounmap(gpio);
435
436 return ret; 363 return ret;
437} 364}
438 365