Move SPI controller code into a common location.

Moves mutual exclusion code to atheros.h, which handles
enabling/disabling the temperature sensor pin when attempting to grab
a lock for SPI operations.

The common location is necessary for the proper functioning of the
temperature sensor driver (pending), as it shares the MISO and CLK pins
with the flash storage device.

Change-Id: I00d18b16f552f1f30e4ff477eb7838ca52e7a5c2
diff --git a/Module.symvers b/Module.symvers
index ca8fad2..eec88df 100644
--- a/Module.symvers
+++ b/Module.symvers
@@ -57,6 +57,8 @@
 0x00000000	register_console	vmlinux	EXPORT_SYMBOL
 0x00000000	sock_no_socketpair	vmlinux	EXPORT_SYMBOL
 0x00000000	input_ff_event	vmlinux	EXPORT_SYMBOL_GPL
+0x00000000	ath_spi_up	vmlinux	EXPORT_SYMBOL
+0x00000000	ath_spi_down	vmlinux	EXPORT_SYMBOL
 0x00000000	dev_addr_del	vmlinux	EXPORT_SYMBOL
 0x00000000	gnet_stats_start_copy	vmlinux	EXPORT_SYMBOL
 0x00000000	tcp_tso_segment	vmlinux	EXPORT_SYMBOL
@@ -303,7 +305,6 @@
 0x00000000	fuse_conn_put	vmlinux	EXPORT_SYMBOL_GPL
 0x00000000	bio_alloc_bioset	vmlinux	EXPORT_SYMBOL
 0x00000000	usb_driver_set_configuration	vmlinux	EXPORT_SYMBOL_GPL
-0x00000000	ath_flash_spi_up	vmlinux	EXPORT_SYMBOL
 0x00000000	mii_ethtool_gset	vmlinux	EXPORT_SYMBOL
 0x00000000	mii_ethtool_sset	vmlinux	EXPORT_SYMBOL
 0x00000000	vfs_cancel_lock	vmlinux	EXPORT_SYMBOL_GPL
@@ -1604,7 +1605,6 @@
 0x00000000	dev_mc_unsync	vmlinux	EXPORT_SYMBOL
 0x00000000	shm_align_mask	vmlinux	EXPORT_SYMBOL
 0x00000000	bus_get_kset	vmlinux	EXPORT_SYMBOL_GPL
-0x00000000	ath_spi_up	vmlinux	EXPORT_SYMBOL
 0x00000000	parse_mtd_partitions	vmlinux	EXPORT_SYMBOL_GPL
 0x00000000	devres_alloc	vmlinux	EXPORT_SYMBOL_GPL
 0x00000000	sysdev_unregister	vmlinux	EXPORT_SYMBOL_GPL
@@ -1798,7 +1798,6 @@
 0x00000000	mnt_pin	vmlinux	EXPORT_SYMBOL
 0x00000000	set_create_files_as	vmlinux	EXPORT_SYMBOL
 0x00000000	dev_get_by_name	vmlinux	EXPORT_SYMBOL
-0x00000000	ath_flash_spi_down	vmlinux	EXPORT_SYMBOL
 0x00000000	__page_symlink	vmlinux	EXPORT_SYMBOL
 0x00000000	install_exec_creds	vmlinux	EXPORT_SYMBOL
 0x00000000	sched_setscheduler	vmlinux	EXPORT_SYMBOL_GPL
@@ -1807,7 +1806,6 @@
 0x00000000	snd_ctl_register_ioctl	sound/core/snd	EXPORT_SYMBOL
 0x00000000	ip_mc_rejoin_group	vmlinux	EXPORT_SYMBOL
 0x00000000	udp_prot	vmlinux	EXPORT_SYMBOL
-0x00000000	ath_spi_down	vmlinux	EXPORT_SYMBOL
 0x00000000	ath_config_slave_mdio_gpios	vmlinux	EXPORT_SYMBOL
 0x00000000	avenrun	vmlinux	EXPORT_SYMBOL
 0x00000000	register_mtd_parser	vmlinux	EXPORT_SYMBOL_GPL
diff --git a/arch/mips/atheros/misc.c b/arch/mips/atheros/misc.c
index 9962186..2bceb24 100755
--- a/arch/mips/atheros/misc.c
+++ b/arch/mips/atheros/misc.c
@@ -307,14 +307,14 @@
 /* drive bits in mask low */
 void ath_gpio_drive_low(unsigned int mask)
 {
-	ath_reg_wr(ATH_GPIO_CLEAR, mask);
+	ath_reg_wr_nf(ATH_GPIO_CLEAR, mask);
 	ath_reg_rmw_set(ATH_GPIO_OE, mask);
 }
 
 /* drive bits in mask high */
 void ath_gpio_drive_high(unsigned int mask)
 {
-	ath_reg_wr(ATH_GPIO_SET, mask);
+	ath_reg_wr_nf(ATH_GPIO_SET, mask);
 	ath_reg_rmw_set(ATH_GPIO_OE, mask);
 }
 
@@ -582,7 +582,10 @@
 void ath_spi_init(void)
 {
 	init_MUTEX(&ath_spi_sem);
+#if !(defined(CONFIG_MACH_AR934x) || defined(CONFIG_MACH_QCA955x) || \
+	defined(CONFIG_MACH_QCA953x) || defined(CONFIG_MACH_QCA956x))
 	ath_reg_wr_nf(ATH_SPI_CLOCK, 0x43);
+#endif
 }
 
 void ath_spi_down(void)
diff --git a/arch/mips/include/asm/mach-atheros/atheros.h b/arch/mips/include/asm/mach-atheros/atheros.h
index 5386f47..1eecc44 100755
--- a/arch/mips/include/asm/mach-atheros/atheros.h
+++ b/arch/mips/include/asm/mach-atheros/atheros.h
@@ -242,6 +242,57 @@
 void ath_spi_flash_write_page(unsigned int addr, unsigned char *data, int len);
 void ath_spi_flash_sector_erase(unsigned int addr);
 
+/*****************************************************************************
+ *   WindCharger SPI Control Functions.
+ *
+ *   GFMN Schematics shares MISO and CLK wires on the Flash storage as well as
+ *   on the LM temperature sensor.  Chip select is handled by driving low on
+ *   either pin 14 (for LM sensor), or pin 5 (for Flash storage).  These
+ *   functions are to allow mutual exclusion when accessing either the file
+ *   system or the temperature sensor.
+ *
+ *****************************************************************************/
+
+#define ATH_MN_TEMP_SENSOR_PIN (1 << 14)
+
+/* Enables flash CS. Blocking for mutual exclusion GPIO on pin 14. */
+static inline void
+ath_mn_spi_enable_flash_cs(void)
+{
+  ath_spi_down();
+  ath_spi_enable_soft_access();
+  /*
+   * Only handles the temp sensor pin, as the flash driver deals with GPIO pin 5
+   * on its own.
+   */
+  ath_gpio_drive_high(ATH_MN_TEMP_SENSOR_PIN);
+}
+
+/* Enables LM sensor CS pin.  Blocking for mutual exclusion GPIO on pin 14. */
+static inline void
+ath_mn_spi_enable_lm_cs(void)
+{
+  ath_spi_down();
+  ath_spi_enable_soft_access();
+  /*
+   * Only handles the temp sensor pin, as the flash driver deals with GPIO pin 5
+   * on its own.
+   */
+  ath_gpio_drive_low(ATH_MN_TEMP_SENSOR_PIN);  /* Enables temp sensor pin. */
+}
+
+/* Releases chipselect. */
+static inline void
+ath_mn_spi_disable_cs(void)
+{
+  ath_gpio_drive_high(ATH_MN_TEMP_SENSOR_PIN);
+  ath_spi_disable_soft_access();
+  ath_spi_up();
+}
+
+
+/*****************************************************************************/
+
 /*
  * Allow access to cs0-2 when GPIO Function enables cs0-2 through SPI register.
  */
diff --git a/drivers/mtd/devices/ath_flash.c b/drivers/mtd/devices/ath_flash.c
index 982fc2a..90fb0f3 100755
--- a/drivers/mtd/devices/ath_flash.c
+++ b/drivers/mtd/devices/ath_flash.c
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/semaphore.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <asm/delay.h>
@@ -53,24 +52,6 @@
 
 static const char *part_probes[] __initdata = { "cmdlinepart", "RedBoot", NULL };
 
-static DECLARE_MUTEX(ath_flash_sem);
-
-/* GLOBAL FUNCTIONS */
-void
-ath_flash_spi_down(void)
-{
-	down(&ath_flash_sem);
-}
-
-void
-ath_flash_spi_up(void)
-{
-	up(&ath_flash_sem);
-}
-
-EXPORT_SYMBOL(ath_flash_spi_down);
-EXPORT_SYMBOL(ath_flash_spi_up);
-
 #define ATH_FLASH_SIZE_2MB          (2*1024*1024)
 #define ATH_FLASH_SIZE_4MB          (4*1024*1024)
 #define ATH_FLASH_SIZE_8MB          (8*1024*1024)
@@ -123,7 +104,7 @@
 	if (instr->addr + instr->len > mtd->size)
 		return (-EINVAL);
 
-	ath_flash_spi_down();
+	ath_mn_spi_enable_flash_cs();
 
 	res = instr->len;
 	do_div(res, mtd->erasesize);
@@ -144,7 +125,7 @@
 
 	ath_spi_done();
 
-	ath_flash_spi_up();
+	ath_mn_spi_disable_cs();
 
 	if (instr->callback) {
 		instr->state |= MTD_ERASE_DONE;
@@ -166,7 +147,7 @@
 		return (-EINVAL);
 	}
 
-	ath_flash_spi_down();
+	ath_mn_spi_enable_flash_cs();
 
 	ath_spi_write_enable();
 	ath_spi_bit_banger(ATH_SPI_CMD_READ);
@@ -178,7 +159,7 @@
 	ath_spi_go();
 	ath_spi_done();
 
-	ath_flash_spi_up();
+	ath_mn_spi_disable_cs();
 
 	*retlen = len;
 	return 0;
@@ -228,7 +209,7 @@
 	uint32_t addr = 0;
 	u_char *mem;
 
-	ath_flash_spi_down();
+	ath_mn_spi_enable_flash_cs();
 
 	while (total < len) {
 		mem = (u_char *) (buf + total);
@@ -243,7 +224,7 @@
 
 	ath_spi_done();
 
-	ath_flash_spi_up();
+	ath_mn_spi_disable_cs();
 
 	*retlen = len;
 	return 0;
@@ -343,7 +324,11 @@
 	struct mtd_partition *mtd_parts;
 	uint8_t index;
 
-	init_MUTEX(&ath_flash_sem);
+        /*
+         * TODO(awdavies) This needs to be moved to a common module outside of
+         * ath_flash.c
+         */
+        ath_spi_init();
 
 #if !(defined(CONFIG_MACH_AR934x) || defined(CONFIG_MACH_QCA955x) || defined(CONFIG_MACH_QCA953x) || defined(CONFIG_MACH_QCA956x))
 #if defined(ATH_SST_FLASH)
@@ -392,6 +377,8 @@
 		}
 	}
 
+        /* Sanity check for module load order. */
+        printk(KERN_NOTICE "ath_flash driver initialized.");
 	return 0;
 }