aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/boards/board-ap325rxa.c52
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c79
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c33
-rw-r--r--arch/sh/boards/mach-migor/setup.c52
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c33
-rw-r--r--drivers/mfd/Kconfig8
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/sh_mobile_sdhi.c145
-rw-r--r--drivers/mmc/host/Kconfig2
9 files changed, 355 insertions, 50 deletions
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index 2d080732a964..b95deee35e0f 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -20,8 +20,6 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/smsc911x.h> 21#include <linux/smsc911x.h>
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/spi/spi.h>
24#include <linux/spi/spi_gpio.h>
25#include <media/ov772x.h> 23#include <media/ov772x.h>
26#include <media/soc_camera.h> 24#include <media/soc_camera.h>
27#include <media/soc_camera_platform.h> 25#include <media/soc_camera_platform.h>
@@ -409,17 +407,25 @@ static struct platform_device ceu_device = {
409 }, 407 },
410}; 408};
411 409
412struct spi_gpio_platform_data sdcard_cn3_platform_data = { 410static struct resource sdhi0_cn3_resources[] = {
413 .sck = GPIO_PTD0, 411 [0] = {
414 .mosi = GPIO_PTD1, 412 .name = "SDHI0",
415 .miso = GPIO_PTD2, 413 .start = 0x04ce0000,
416 .num_chipselect = 1, 414 .end = 0x04ce01ff,
415 .flags = IORESOURCE_MEM,
416 },
417 [1] = {
418 .start = 101,
419 .flags = IORESOURCE_IRQ,
420 },
417}; 421};
418 422
419static struct platform_device sdcard_cn3_device = { 423static struct platform_device sdhi0_cn3_device = {
420 .name = "spi_gpio", 424 .name = "sh_mobile_sdhi",
421 .dev = { 425 .num_resources = ARRAY_SIZE(sdhi0_cn3_resources),
422 .platform_data = &sdcard_cn3_platform_data, 426 .resource = sdhi0_cn3_resources,
427 .archdata = {
428 .hwblk_id = HWBLK_SDHI0,
423 }, 429 },
424}; 430};
425 431
@@ -470,20 +476,11 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
470 &lcdc_device, 476 &lcdc_device,
471 &ceu_device, 477 &ceu_device,
472 &nand_flash_device, 478 &nand_flash_device,
473 &sdcard_cn3_device, 479 &sdhi0_cn3_device,
474 &ap325rxa_camera[0], 480 &ap325rxa_camera[0],
475 &ap325rxa_camera[1], 481 &ap325rxa_camera[1],
476}; 482};
477 483
478static struct spi_board_info ap325rxa_spi_devices[] = {
479 {
480 .modalias = "mmc_spi",
481 .max_speed_hz = 5000000,
482 .chip_select = 0,
483 .controller_data = (void *) GPIO_PTD5,
484 },
485};
486
487static int __init ap325rxa_devices_setup(void) 484static int __init ap325rxa_devices_setup(void)
488{ 485{
489 /* LD3 and LD4 LEDs */ 486 /* LD3 and LD4 LEDs */
@@ -578,12 +575,19 @@ static int __init ap325rxa_devices_setup(void)
578 575
579 platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20); 576 platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
580 577
578 /* SDHI0 */
579 gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
580 gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
581 gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
582 gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
583 gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
584 gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
585 gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
586 gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
587
581 i2c_register_board_info(0, ap325rxa_i2c_devices, 588 i2c_register_board_info(0, ap325rxa_i2c_devices,
582 ARRAY_SIZE(ap325rxa_i2c_devices)); 589 ARRAY_SIZE(ap325rxa_i2c_devices));
583 590
584 spi_register_board_info(ap325rxa_spi_devices,
585 ARRAY_SIZE(ap325rxa_spi_devices));
586
587 return platform_add_devices(ap325rxa_devices, 591 return platform_add_devices(ap325rxa_devices,
588 ARRAY_SIZE(ap325rxa_devices)); 592 ARRAY_SIZE(ap325rxa_devices));
589} 593}
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 3b1ceb46fa54..9d15196952a0 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -428,6 +428,54 @@ static struct i2c_board_info ts_i2c_clients = {
428 .irq = IRQ0, 428 .irq = IRQ0,
429}; 429};
430 430
431/* SHDI0 */
432static struct resource sdhi0_resources[] = {
433 [0] = {
434 .name = "SDHI0",
435 .start = 0x04ce0000,
436 .end = 0x04ce01ff,
437 .flags = IORESOURCE_MEM,
438 },
439 [1] = {
440 .start = 101,
441 .flags = IORESOURCE_IRQ,
442 },
443};
444
445static struct platform_device sdhi0_device = {
446 .name = "sh_mobile_sdhi",
447 .num_resources = ARRAY_SIZE(sdhi0_resources),
448 .resource = sdhi0_resources,
449 .id = 0,
450 .archdata = {
451 .hwblk_id = HWBLK_SDHI0,
452 },
453};
454
455/* SHDI1 */
456static struct resource sdhi1_resources[] = {
457 [0] = {
458 .name = "SDHI1",
459 .start = 0x04cf0000,
460 .end = 0x04cf01ff,
461 .flags = IORESOURCE_MEM,
462 },
463 [1] = {
464 .start = 24,
465 .flags = IORESOURCE_IRQ,
466 },
467};
468
469static struct platform_device sdhi1_device = {
470 .name = "sh_mobile_sdhi",
471 .num_resources = ARRAY_SIZE(sdhi1_resources),
472 .resource = sdhi1_resources,
473 .id = 1,
474 .archdata = {
475 .hwblk_id = HWBLK_SDHI1,
476 },
477};
478
431static struct platform_device *ecovec_devices[] __initdata = { 479static struct platform_device *ecovec_devices[] __initdata = {
432 &heartbeat_device, 480 &heartbeat_device,
433 &nor_flash_device, 481 &nor_flash_device,
@@ -438,6 +486,8 @@ static struct platform_device *ecovec_devices[] __initdata = {
438 &ceu0_device, 486 &ceu0_device,
439 &ceu1_device, 487 &ceu1_device,
440 &keysc_device, 488 &keysc_device,
489 &sdhi0_device,
490 &sdhi1_device,
441}; 491};
442 492
443#define EEPROM_ADDR 0x50 493#define EEPROM_ADDR 0x50
@@ -710,6 +760,34 @@ static int __init arch_setup(void)
710 gpio_direction_input(GPIO_PTR5); 760 gpio_direction_input(GPIO_PTR5);
711 gpio_direction_input(GPIO_PTR6); 761 gpio_direction_input(GPIO_PTR6);
712 762
763 /* enable SDHI0 */
764 gpio_request(GPIO_FN_SDHI0CD, NULL);
765 gpio_request(GPIO_FN_SDHI0WP, NULL);
766 gpio_request(GPIO_FN_SDHI0CMD, NULL);
767 gpio_request(GPIO_FN_SDHI0CLK, NULL);
768 gpio_request(GPIO_FN_SDHI0D3, NULL);
769 gpio_request(GPIO_FN_SDHI0D2, NULL);
770 gpio_request(GPIO_FN_SDHI0D1, NULL);
771 gpio_request(GPIO_FN_SDHI0D0, NULL);
772
773 /* enable SDHI1 */
774 gpio_request(GPIO_FN_SDHI1CD, NULL);
775 gpio_request(GPIO_FN_SDHI1WP, NULL);
776 gpio_request(GPIO_FN_SDHI1CMD, NULL);
777 gpio_request(GPIO_FN_SDHI1CLK, NULL);
778 gpio_request(GPIO_FN_SDHI1D3, NULL);
779 gpio_request(GPIO_FN_SDHI1D2, NULL);
780 gpio_request(GPIO_FN_SDHI1D1, NULL);
781 gpio_request(GPIO_FN_SDHI1D0, NULL);
782
783 gpio_request(GPIO_PTB6, NULL);
784 gpio_request(GPIO_PTB7, NULL);
785 gpio_direction_output(GPIO_PTB6, 1);
786 gpio_direction_output(GPIO_PTB7, 1);
787
788 /* I/O buffer drive ability is high for SDHI1 */
789 ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA);
790
713 /* enable I2C device */ 791 /* enable I2C device */
714 i2c_register_board_info(1, i2c1_devices, 792 i2c_register_board_info(1, i2c1_devices,
715 ARRAY_SIZE(i2c1_devices)); 793 ARRAY_SIZE(i2c1_devices));
@@ -726,7 +804,6 @@ static int __init devices_setup(void)
726} 804}
727device_initcall(devices_setup); 805device_initcall(devices_setup);
728 806
729
730static struct sh_machine_vector mv_ecovec __initmv = { 807static struct sh_machine_vector mv_ecovec __initmv = {
731 .mv_name = "R0P7724 (EcoVec)", 808 .mv_name = "R0P7724 (EcoVec)",
732}; 809};
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index ce01d6a953b8..43d75ee93358 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -332,6 +332,28 @@ static struct platform_device kfr2r09_camera = {
332 }, 332 },
333}; 333};
334 334
335static struct resource kfr2r09_sh_sdhi0_resources[] = {
336 [0] = {
337 .name = "SDHI0",
338 .start = 0x04ce0000,
339 .end = 0x04ce01ff,
340 .flags = IORESOURCE_MEM,
341 },
342 [1] = {
343 .start = 101,
344 .flags = IORESOURCE_IRQ,
345 },
346};
347
348static struct platform_device kfr2r09_sh_sdhi0_device = {
349 .name = "sh_mobile_sdhi",
350 .num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources),
351 .resource = kfr2r09_sh_sdhi0_resources,
352 .archdata = {
353 .hwblk_id = HWBLK_SDHI0,
354 },
355};
356
335static struct platform_device *kfr2r09_devices[] __initdata = { 357static struct platform_device *kfr2r09_devices[] __initdata = {
336 &kfr2r09_nor_flash_device, 358 &kfr2r09_nor_flash_device,
337 &kfr2r09_nand_flash_device, 359 &kfr2r09_nand_flash_device,
@@ -339,6 +361,7 @@ static struct platform_device *kfr2r09_devices[] __initdata = {
339 &kfr2r09_sh_lcdc_device, 361 &kfr2r09_sh_lcdc_device,
340 &kfr2r09_ceu_device, 362 &kfr2r09_ceu_device,
341 &kfr2r09_camera, 363 &kfr2r09_camera,
364 &kfr2r09_sh_sdhi0_device,
342}; 365};
343 366
344#define BSC_CS0BCR 0xfec10004 367#define BSC_CS0BCR 0xfec10004
@@ -500,6 +523,16 @@ static int __init kfr2r09_devices_setup(void)
500 523
501 platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20); 524 platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20);
502 525
526 /* SDHI0 connected to yc304 */
527 gpio_request(GPIO_FN_SDHI0CD, NULL);
528 gpio_request(GPIO_FN_SDHI0WP, NULL);
529 gpio_request(GPIO_FN_SDHI0D3, NULL);
530 gpio_request(GPIO_FN_SDHI0D2, NULL);
531 gpio_request(GPIO_FN_SDHI0D1, NULL);
532 gpio_request(GPIO_FN_SDHI0D0, NULL);
533 gpio_request(GPIO_FN_SDHI0CMD, NULL);
534 gpio_request(GPIO_FN_SDHI0CLK, NULL);
535
503 return platform_add_devices(kfr2r09_devices, 536 return platform_add_devices(kfr2r09_devices,
504 ARRAY_SIZE(kfr2r09_devices)); 537 ARRAY_SIZE(kfr2r09_devices));
505} 538}
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 6ed1fd32369e..8e911360c91e 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -18,8 +18,6 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/gpio.h> 20#include <linux/gpio.h>
21#include <linux/spi/spi.h>
22#include <linux/spi/spi_gpio.h>
23#include <video/sh_mobile_lcdc.h> 21#include <video/sh_mobile_lcdc.h>
24#include <media/sh_mobile_ceu.h> 22#include <media/sh_mobile_ceu.h>
25#include <media/ov772x.h> 23#include <media/ov772x.h>
@@ -390,17 +388,25 @@ static struct platform_device migor_ceu_device = {
390 }, 388 },
391}; 389};
392 390
393struct spi_gpio_platform_data sdcard_cn9_platform_data = { 391static struct resource sdhi_cn9_resources[] = {
394 .sck = GPIO_PTD0, 392 [0] = {
395 .mosi = GPIO_PTD1, 393 .name = "SDHI",
396 .miso = GPIO_PTD2, 394 .start = 0x04ce0000,
397 .num_chipselect = 1, 395 .end = 0x04ce01ff,
396 .flags = IORESOURCE_MEM,
397 },
398 [1] = {
399 .start = 101,
400 .flags = IORESOURCE_IRQ,
401 },
398}; 402};
399 403
400static struct platform_device sdcard_cn9_device = { 404static struct platform_device sdhi_cn9_device = {
401 .name = "spi_gpio", 405 .name = "sh_mobile_sdhi",
402 .dev = { 406 .num_resources = ARRAY_SIZE(sdhi_cn9_resources),
403 .platform_data = &sdcard_cn9_platform_data, 407 .resource = sdhi_cn9_resources,
408 .archdata = {
409 .hwblk_id = HWBLK_SDHI,
404 }, 410 },
405}; 411};
406 412
@@ -467,20 +473,11 @@ static struct platform_device *migor_devices[] __initdata = {
467 &migor_ceu_device, 473 &migor_ceu_device,
468 &migor_nor_flash_device, 474 &migor_nor_flash_device,
469 &migor_nand_flash_device, 475 &migor_nand_flash_device,
470 &sdcard_cn9_device, 476 &sdhi_cn9_device,
471 &migor_camera[0], 477 &migor_camera[0],
472 &migor_camera[1], 478 &migor_camera[1],
473}; 479};
474 480
475static struct spi_board_info migor_spi_devices[] = {
476 {
477 .modalias = "mmc_spi",
478 .max_speed_hz = 5000000,
479 .chip_select = 0,
480 .controller_data = (void *) GPIO_PTD5,
481 },
482};
483
484static int __init migor_devices_setup(void) 481static int __init migor_devices_setup(void)
485{ 482{
486 483
@@ -525,6 +522,16 @@ static int __init migor_devices_setup(void)
525 gpio_request(GPIO_PTA1, NULL); 522 gpio_request(GPIO_PTA1, NULL);
526 gpio_direction_input(GPIO_PTA1); 523 gpio_direction_input(GPIO_PTA1);
527 524
525 /* SDHI */
526 gpio_request(GPIO_FN_SDHICD, NULL);
527 gpio_request(GPIO_FN_SDHIWP, NULL);
528 gpio_request(GPIO_FN_SDHID3, NULL);
529 gpio_request(GPIO_FN_SDHID2, NULL);
530 gpio_request(GPIO_FN_SDHID1, NULL);
531 gpio_request(GPIO_FN_SDHID0, NULL);
532 gpio_request(GPIO_FN_SDHICMD, NULL);
533 gpio_request(GPIO_FN_SDHICLK, NULL);
534
528 /* Touch Panel */ 535 /* Touch Panel */
529 gpio_request(GPIO_FN_IRQ6, NULL); 536 gpio_request(GPIO_FN_IRQ6, NULL);
530 537
@@ -612,9 +619,6 @@ static int __init migor_devices_setup(void)
612 i2c_register_board_info(0, migor_i2c_devices, 619 i2c_register_board_info(0, migor_i2c_devices,
613 ARRAY_SIZE(migor_i2c_devices)); 620 ARRAY_SIZE(migor_i2c_devices));
614 621
615 spi_register_board_info(migor_spi_devices,
616 ARRAY_SIZE(migor_spi_devices));
617
618 return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); 622 return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
619} 623}
620arch_initcall(migor_devices_setup); 624arch_initcall(migor_devices_setup);
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index e78c3be8ad2f..ce6b36ebe64d 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -448,6 +448,28 @@ static struct platform_device sh7724_usb1_gadget_device = {
448 .resource = sh7724_usb1_gadget_resources, 448 .resource = sh7724_usb1_gadget_resources,
449}; 449};
450 450
451static struct resource sdhi0_cn7_resources[] = {
452 [0] = {
453 .name = "SDHI0",
454 .start = 0x04ce0000,
455 .end = 0x04ce01ff,
456 .flags = IORESOURCE_MEM,
457 },
458 [1] = {
459 .start = 101,
460 .flags = IORESOURCE_IRQ,
461 },
462};
463
464static struct platform_device sdhi0_cn7_device = {
465 .name = "sh_mobile_sdhi",
466 .num_resources = ARRAY_SIZE(sdhi0_cn7_resources),
467 .resource = sdhi0_cn7_resources,
468 .archdata = {
469 .hwblk_id = HWBLK_SDHI0,
470 },
471};
472
451static struct platform_device *ms7724se_devices[] __initdata = { 473static struct platform_device *ms7724se_devices[] __initdata = {
452 &heartbeat_device, 474 &heartbeat_device,
453 &smc91x_eth_device, 475 &smc91x_eth_device,
@@ -460,6 +482,7 @@ static struct platform_device *ms7724se_devices[] __initdata = {
460 &sh7724_usb0_host_device, 482 &sh7724_usb0_host_device,
461 &sh7724_usb1_gadget_device, 483 &sh7724_usb1_gadget_device,
462 &fsi_device, 484 &fsi_device,
485 &sdhi0_cn7_device,
463}; 486};
464 487
465#define EEPROM_OP 0xBA206000 488#define EEPROM_OP 0xBA206000
@@ -698,6 +721,16 @@ static int __init devices_setup(void)
698 clk_set_rate(&fsimcka_clk, 11000); 721 clk_set_rate(&fsimcka_clk, 11000);
699 clk_put(fsia_clk); 722 clk_put(fsia_clk);
700 723
724 /* SDHI0 connected to cn7 */
725 gpio_request(GPIO_FN_SDHI0CD, NULL);
726 gpio_request(GPIO_FN_SDHI0WP, NULL);
727 gpio_request(GPIO_FN_SDHI0D3, NULL);
728 gpio_request(GPIO_FN_SDHI0D2, NULL);
729 gpio_request(GPIO_FN_SDHI0D1, NULL);
730 gpio_request(GPIO_FN_SDHI0D0, NULL);
731 gpio_request(GPIO_FN_SDHI0CMD, NULL);
732 gpio_request(GPIO_FN_SDHI0CLK, NULL);
733
701 /* 734 /*
702 * enable SH-Eth 735 * enable SH-Eth
703 * 736 *
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 570be139f9df..96956b3cc178 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -35,6 +35,14 @@ config MFD_ASIC3
35 This driver supports the ASIC3 multifunction chip found on many 35 This driver supports the ASIC3 multifunction chip found on many
36 PDAs (mainly iPAQ and HTC based ones) 36 PDAs (mainly iPAQ and HTC based ones)
37 37
38config MFD_SH_MOBILE_SDHI
39 bool "Support for SuperH Mobile SDHI"
40 depends on SUPERH
41 select MFD_CORE
42 ---help---
43 This driver supports the SDHI hardware block found in many
44 SuperH Mobile SoCs.
45
38config MFD_DM355EVM_MSP 46config MFD_DM355EVM_MSP
39 bool "DaVinci DM355 EVM microcontroller" 47 bool "DaVinci DM355 EVM microcontroller"
40 depends on I2C && MACH_DAVINCI_DM355_EVM 48 depends on I2C && MACH_DAVINCI_DM355_EVM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f3b277b90d40..d9522943d2fb 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_MFD_SM501) += sm501.o 5obj-$(CONFIG_MFD_SM501) += sm501.o
6obj-$(CONFIG_MFD_ASIC3) += asic3.o 6obj-$(CONFIG_MFD_ASIC3) += asic3.o
7obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
7 8
8obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o 9obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
9obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 10obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
new file mode 100644
index 000000000000..56f72cc1d569
--- /dev/null
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -0,0 +1,145 @@
1/*
2 * SuperH Mobile SDHI
3 *
4 * Copyright (C) 2009 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Based on "Compaq ASIC3 support":
11 *
12 * Copyright 2001 Compaq Computer Corporation.
13 * Copyright 2004-2005 Phil Blundell
14 * Copyright 2007-2008 OpenedHand Ltd.
15 *
16 * Authors: Phil Blundell <pb@handhelds.org>,
17 * Samuel Ortiz <sameo@openedhand.com>
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24
25#include <linux/mfd/core.h>
26#include <linux/mfd/tmio.h>
27
28struct sh_mobile_sdhi {
29 struct clk *clk;
30 struct tmio_mmc_data mmc_data;
31 struct mfd_cell cell_mmc;
32};
33
34static struct resource sh_mobile_sdhi_resources[] = {
35 {
36 .start = 0x000,
37 .end = 0x1ff,
38 .flags = IORESOURCE_MEM,
39 },
40 {
41 .start = 0,
42 .end = 0,
43 .flags = IORESOURCE_IRQ,
44 },
45};
46
47static struct mfd_cell sh_mobile_sdhi_cell = {
48 .name = "tmio-mmc",
49 .num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),
50 .resources = sh_mobile_sdhi_resources,
51};
52
53static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
54{
55 struct sh_mobile_sdhi *priv;
56 struct resource *mem;
57 char clk_name[8];
58 int ret, irq;
59
60 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
61 if (!mem)
62 dev_err(&pdev->dev, "missing MEM resource\n");
63
64 irq = platform_get_irq(pdev, 0);
65 if (irq < 0)
66 dev_err(&pdev->dev, "missing IRQ resource\n");
67
68 if (!mem || (irq < 0))
69 return -EINVAL;
70
71 priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
72 if (priv == NULL) {
73 dev_err(&pdev->dev, "kzalloc failed\n");
74 return -ENOMEM;
75 }
76
77 snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
78 priv->clk = clk_get(&pdev->dev, clk_name);
79 if (IS_ERR(priv->clk)) {
80 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
81 ret = PTR_ERR(priv->clk);
82 kfree(priv);
83 return ret;
84 }
85
86 clk_enable(priv->clk);
87
88 /* FIXME: silly const unsigned int hclk */
89 *(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);
90
91 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
92 priv->cell_mmc.driver_data = &priv->mmc_data;
93 priv->cell_mmc.platform_data = &priv->cell_mmc;
94 priv->cell_mmc.data_size = sizeof(priv->cell_mmc);
95
96 platform_set_drvdata(pdev, priv);
97
98 ret = mfd_add_devices(&pdev->dev, pdev->id,
99 &priv->cell_mmc, 1, mem, irq);
100 if (ret) {
101 clk_disable(priv->clk);
102 clk_put(priv->clk);
103 kfree(priv);
104 }
105
106 return ret;
107}
108
109static int sh_mobile_sdhi_remove(struct platform_device *pdev)
110{
111 struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev);
112
113 mfd_remove_devices(&pdev->dev);
114 clk_disable(priv->clk);
115 clk_put(priv->clk);
116 kfree(priv);
117
118 return 0;
119}
120
121static struct platform_driver sh_mobile_sdhi_driver = {
122 .driver = {
123 .name = "sh_mobile_sdhi",
124 .owner = THIS_MODULE,
125 },
126 .probe = sh_mobile_sdhi_probe,
127 .remove = __devexit_p(sh_mobile_sdhi_remove),
128};
129
130static int __init sh_mobile_sdhi_init(void)
131{
132 return platform_driver_register(&sh_mobile_sdhi_driver);
133}
134
135static void __exit sh_mobile_sdhi_exit(void)
136{
137 platform_driver_unregister(&sh_mobile_sdhi_driver);
138}
139
140module_init(sh_mobile_sdhi_init);
141module_exit(sh_mobile_sdhi_exit);
142
143MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
144MODULE_AUTHOR("Magnus Damm");
145MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 432ae8358c86..e04b751680d0 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -329,7 +329,7 @@ config MMC_SDRICOH_CS
329 329
330config MMC_TMIO 330config MMC_TMIO
331 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" 331 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
332 depends on MFD_TMIO || MFD_ASIC3 332 depends on MFD_TMIO || MFD_ASIC3 || SUPERH
333 help 333 help
334 This provides support for the SD/MMC cell found in TC6393XB, 334 This provides support for the SD/MMC cell found in TC6393XB,
335 T7L66XB and also HTC ASIC3 335 T7L66XB and also HTC ASIC3