diff options
Diffstat (limited to 'drivers/mfd/asic3.c')
-rw-r--r-- | drivers/mfd/asic3.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 63a2a6632106..7de708d15d72 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/slab.h> | ||
24 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
26 | 27 | ||
@@ -80,6 +81,7 @@ struct asic3 { | |||
80 | u16 irq_bothedge[4]; | 81 | u16 irq_bothedge[4]; |
81 | struct gpio_chip gpio; | 82 | struct gpio_chip gpio; |
82 | struct device *dev; | 83 | struct device *dev; |
84 | void __iomem *tmio_cnf; | ||
83 | 85 | ||
84 | struct asic3_clk clocks[ARRAY_SIZE(asic3_clk_init)]; | 86 | struct asic3_clk clocks[ARRAY_SIZE(asic3_clk_init)]; |
85 | }; | 87 | }; |
@@ -685,8 +687,24 @@ static struct mfd_cell asic3_cell_ds1wm = { | |||
685 | .resources = ds1wm_resources, | 687 | .resources = ds1wm_resources, |
686 | }; | 688 | }; |
687 | 689 | ||
690 | static void asic3_mmc_pwr(struct platform_device *pdev, int state) | ||
691 | { | ||
692 | struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); | ||
693 | |||
694 | tmio_core_mmc_pwr(asic->tmio_cnf, 1 - asic->bus_shift, state); | ||
695 | } | ||
696 | |||
697 | static void asic3_mmc_clk_div(struct platform_device *pdev, int state) | ||
698 | { | ||
699 | struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); | ||
700 | |||
701 | tmio_core_mmc_clk_div(asic->tmio_cnf, 1 - asic->bus_shift, state); | ||
702 | } | ||
703 | |||
688 | static struct tmio_mmc_data asic3_mmc_data = { | 704 | static struct tmio_mmc_data asic3_mmc_data = { |
689 | .hclk = 24576000, | 705 | .hclk = 24576000, |
706 | .set_pwr = asic3_mmc_pwr, | ||
707 | .set_clk_div = asic3_mmc_clk_div, | ||
690 | }; | 708 | }; |
691 | 709 | ||
692 | static struct resource asic3_mmc_resources[] = { | 710 | static struct resource asic3_mmc_resources[] = { |
@@ -696,11 +714,6 @@ static struct resource asic3_mmc_resources[] = { | |||
696 | .flags = IORESOURCE_MEM, | 714 | .flags = IORESOURCE_MEM, |
697 | }, | 715 | }, |
698 | { | 716 | { |
699 | .start = ASIC3_SD_CONFIG_BASE, | ||
700 | .end = ASIC3_SD_CONFIG_BASE + 0x1ff, | ||
701 | .flags = IORESOURCE_MEM, | ||
702 | }, | ||
703 | { | ||
704 | .start = 0, | 717 | .start = 0, |
705 | .end = 0, | 718 | .end = 0, |
706 | .flags = IORESOURCE_IRQ, | 719 | .flags = IORESOURCE_IRQ, |
@@ -743,6 +756,10 @@ static int asic3_mmc_enable(struct platform_device *pdev) | |||
743 | asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), | 756 | asic3_set_register(asic, ASIC3_OFFSET(SDHWCTRL, SDCONF), |
744 | ASIC3_SDHWCTRL_SDPWR, 1); | 757 | ASIC3_SDHWCTRL_SDPWR, 1); |
745 | 758 | ||
759 | /* ASIC3_SD_CTRL_BASE assumes 32-bit addressing, TMIO is 16-bit */ | ||
760 | tmio_core_mmc_enable(asic->tmio_cnf, 1 - asic->bus_shift, | ||
761 | ASIC3_SD_CTRL_BASE >> 1); | ||
762 | |||
746 | return 0; | 763 | return 0; |
747 | } | 764 | } |
748 | 765 | ||
@@ -797,10 +814,15 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
797 | asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm); | 814 | asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm); |
798 | 815 | ||
799 | /* MMC */ | 816 | /* MMC */ |
817 | asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + | ||
818 | mem_sdio->start, 0x400 >> asic->bus_shift); | ||
819 | if (!asic->tmio_cnf) { | ||
820 | ret = -ENOMEM; | ||
821 | dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n"); | ||
822 | goto out; | ||
823 | } | ||
800 | asic3_mmc_resources[0].start >>= asic->bus_shift; | 824 | asic3_mmc_resources[0].start >>= asic->bus_shift; |
801 | asic3_mmc_resources[0].end >>= asic->bus_shift; | 825 | asic3_mmc_resources[0].end >>= asic->bus_shift; |
802 | asic3_mmc_resources[1].start >>= asic->bus_shift; | ||
803 | asic3_mmc_resources[1].end >>= asic->bus_shift; | ||
804 | 826 | ||
805 | asic3_cell_mmc.platform_data = &asic3_cell_mmc; | 827 | asic3_cell_mmc.platform_data = &asic3_cell_mmc; |
806 | asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc); | 828 | asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc); |
@@ -820,7 +842,10 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
820 | 842 | ||
821 | static void asic3_mfd_remove(struct platform_device *pdev) | 843 | static void asic3_mfd_remove(struct platform_device *pdev) |
822 | { | 844 | { |
845 | struct asic3 *asic = platform_get_drvdata(pdev); | ||
846 | |||
823 | mfd_remove_devices(&pdev->dev); | 847 | mfd_remove_devices(&pdev->dev); |
848 | iounmap(asic->tmio_cnf); | ||
824 | } | 849 | } |
825 | 850 | ||
826 | /* Core */ | 851 | /* Core */ |
@@ -908,7 +933,7 @@ static int __init asic3_probe(struct platform_device *pdev) | |||
908 | return ret; | 933 | return ret; |
909 | } | 934 | } |
910 | 935 | ||
911 | static int asic3_remove(struct platform_device *pdev) | 936 | static int __devexit asic3_remove(struct platform_device *pdev) |
912 | { | 937 | { |
913 | int ret; | 938 | int ret; |
914 | struct asic3 *asic = platform_get_drvdata(pdev); | 939 | struct asic3 *asic = platform_get_drvdata(pdev); |