msm: 8064: Add SPI Ethernet support for the Rumi3 target

Add the SPI device declarations, GPIO configuration, and
initialization code needed to use the SPI Ethernet
controller found on the APQ8064 Rumi3.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-apq8064.c
index dc74924..45fcd90 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-apq8064.c
@@ -16,6 +16,7 @@
 #include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/msm_ssbi.h>
+#include <linux/spi/spi.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -34,18 +35,6 @@
 
 #include "board-apq8064.h"
 
-static int __init gpiomux_init(void)
-{
-	int rc;
-
-	rc = msm_gpiomux_init(NR_GPIO_IRQS);
-	if (rc) {
-		pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
-		return rc;
-	}
-	return 0;
-}
-
 /* APQ8064 have 4 SDCC controllers */
 enum sdcc_controllers {
 	SDCC1,
@@ -326,6 +315,82 @@
 	.pclk_src_name		= "dfab_usb_hs_clk",
 };
 
+#define KS8851_IRQ_GPIO		43
+
+static struct spi_board_info spi_board_info[] __initdata = {
+	{
+		.modalias               = "ks8851",
+		.irq                    = MSM_GPIO_TO_INT(KS8851_IRQ_GPIO),
+		.max_speed_hz           = 19200000,
+		.bus_num                = 0,
+		.chip_select            = 2,
+		.mode                   = SPI_MODE_0,
+	},
+};
+
+#ifdef CONFIG_KS8851
+static struct gpiomux_setting gpio_eth_config = {
+	.pull = GPIOMUX_PULL_NONE,
+	.drv = GPIOMUX_DRV_8MA,
+	.func = GPIOMUX_FUNC_GPIO,
+};
+
+/* The SPI configurations apply to GSBI 5*/
+static struct gpiomux_setting gpio_spi_config = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+/* The SPI configurations apply to GSBI 5 chip select 2*/
+static struct gpiomux_setting gpio_spi_cs2_config = {
+	.func = GPIOMUX_FUNC_3,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+#endif
+
+struct msm_gpiomux_config apq8064_ethernet_configs[NR_GPIO_IRQS] = {
+#ifdef CONFIG_KS8851
+	{
+		.gpio = KS8851_IRQ_GPIO,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
+			[GPIOMUX_ACTIVE] = &gpio_eth_config,
+		}
+	},
+#endif
+};
+
+static struct msm_gpiomux_config apq8064_gsbi_configs[] __initdata = {
+#ifdef CONFIG_KS8851
+	{
+		.gpio      = 51,		/* GSBI5 QUP SPI_DATA_MOSI */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 52,		/* GSBI5 QUP SPI_DATA_MISO */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 31,		/* GSBI5 QUP SPI_CS2_N */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_cs2_config,
+		},
+	},
+	{
+		.gpio      = 54,		/* GSBI5 QUP SPI_CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+#endif
+};
+
 static struct pm8xxx_mpp_platform_data
 apq8064_pm8921_mpp_pdata __devinitdata = {
 	.mpp_base	= PM8921_MPP_PM_TO_SYS(1),
@@ -396,6 +461,44 @@
 					&apq8064_i2c_qup_gsbi4_pdata;
 }
 
+static int __init gpiomux_init(void)
+{
+	int rc;
+
+	rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	if (rc) {
+		pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
+		return rc;
+	}
+	msm_gpiomux_install(apq8064_ethernet_configs,
+			ARRAY_SIZE(apq8064_ethernet_configs));
+
+	msm_gpiomux_install(apq8064_gsbi_configs,
+			ARRAY_SIZE(apq8064_gsbi_configs));
+	return 0;
+}
+
+#ifdef CONFIG_KS8851
+static int ethernet_init(void)
+{
+	int ret;
+	ret = gpio_request(KS8851_IRQ_GPIO, "ks8851_irq");
+	if (ret) {
+		pr_err("ks8851 gpio_request failed: %d\n", ret);
+		goto fail;
+	}
+
+	return 0;
+fail:
+	return ret;
+}
+#else
+static int ethernet_init(void)
+{
+	return 0;
+}
+#endif
+
 static void __init apq8064_common_init(void)
 {
 	if (socinfo_init() < 0)
@@ -427,7 +530,9 @@
 static void __init apq8064_rumi3_init(void)
 {
 	apq8064_common_init();
+	ethernet_init();
 	platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 }
 
 MACHINE_START(APQ8064_SIM, "QCT APQ8064 SIMULATOR")