summaryrefslogtreecommitdiffstats
path: root/drivers/staging/westbridge/astoria/api/src/cyasintr.c
diff options
context:
space:
mode:
authorDavid Cross2010-08-07 02:29:03 +0200
committerGreg Kroah-Hartman2010-08-31 02:20:53 +0200
commit81eb669b9516b85a2acf4c342db2322bed37d70c (patch)
treed5339b0c1d371b6bfeb0984678ca03054f3a8339 /drivers/staging/westbridge/astoria/api/src/cyasintr.c
parentStaging: delete rtl8192su driver (diff)
downloadkernel-qcow2-linux-81eb669b9516b85a2acf4c342db2322bed37d70c.tar.gz
kernel-qcow2-linux-81eb669b9516b85a2acf4c342db2322bed37d70c.tar.xz
kernel-qcow2-linux-81eb669b9516b85a2acf4c342db2322bed37d70c.zip
Staging: add West Bridge Astoria Driver
This is a driver for the Cypress West Bridge companion chip. Its function is analogous to the North/South Bridges of PC environments applied to embedded devices, in that it expands I/O and storage capabilities of an embedded processor. The Astoria version, which this driver applies to, functions as a USB, embedded memory and SDIO controller. The kernel that this patch was applied to is linux-2.6.35, although it was tested using the android kernel 2.6.29 running on the Zoom 2 platform. In this system, it was used primarily as a sideloading accelerator enabling direct data transfers between a USB host PC and embedded memory without system overheads. Minor modifications were also made to the kernel for this patch. These include changes such as EXPORTing of fat_get_block in the kernel code. Another function, mpage_cleardirty was also added to the memory management code. This function is used to clear the dirty pages from a specific inode. This allows for direct, file based DMA. None of these changes are believed to have any negative impact on the kernel and may provide additional benefit for other developers and drivers. The driver, as submitted, was placed into the drivers/staging/westbridge folder as the directory structure it will eventually reside in is not yet defined. The driver, as placed in staging is divided into four parts: 1) gadget - this implements a gadget peripheral controller and includes IOCTLs for MTP transfers 2) block -this implements a generic block device driver to enable access to embedded memory 3) api -this is the Cypress SDK, and includes USB and Storage specific functions. In addition, it includes common code for low level routines such as message passing and common data transfer routines 4) hal - this should likely be included in the arch directory as it needs to be modified for a given platform. The directory structure in the staging area is meant to reflect the eventual location of where this code likely should be. It is platform specific. In this case, the HAL included is for the Android Zoom 2 platform. Here, West Bridge is connected to the GPMC (general purpose memory controller) of the OMAP3. Specific timing needs to be enabled to ensure reliable communication. Many thanks to Greg KH for conducting initial reviews and providing pointers. Please contact david.cross@cypress.com for questions, concerns or feedback. Signed-off-by: David Cross <david.cross@cypress.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/westbridge/astoria/api/src/cyasintr.c')
-rw-r--r--drivers/staging/westbridge/astoria/api/src/cyasintr.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/drivers/staging/westbridge/astoria/api/src/cyasintr.c b/drivers/staging/westbridge/astoria/api/src/cyasintr.c
new file mode 100644
index 000000000000..aea6c3ebf067
--- /dev/null
+++ b/drivers/staging/westbridge/astoria/api/src/cyasintr.c
@@ -0,0 +1,143 @@
+/* Cypress West Bridge API source file (cyasintr.c)
+## ===========================
+## Copyright (C) 2010 Cypress Semiconductor
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Fifth Floor
+## Boston, MA 02110-1301, USA.
+## ===========================
+*/
+
+#include "../../include/linux/westbridge/cyashal.h"
+#include "../../include/linux/westbridge/cyasdevice.h"
+#include "../../include/linux/westbridge/cyasregs.h"
+#include "../../include/linux/westbridge/cyaserr.h"
+
+extern void cy_as_mail_box_interrupt_handler(cy_as_device *) ;
+
+void
+cy_as_mcu_interrupt_handler(cy_as_device *dev_p)
+{
+ /* Read and clear the interrupt. */
+ uint16_t v ;
+
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_MCU_STAT) ;
+ v = v ;
+}
+
+void
+cy_as_power_management_interrupt_handler(cy_as_device *dev_p)
+{
+ uint16_t v ;
+
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PWR_MAGT_STAT) ;
+ v = v ;
+}
+
+void
+cy_as_pll_lock_loss_interrupt_handler(cy_as_device *dev_p)
+{
+ uint16_t v ;
+
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PLL_LOCK_LOSS_STAT) ;
+ v = v ;
+}
+
+uint32_t cy_as_intr_start(cy_as_device *dev_p, cy_bool dmaintr)
+{
+ uint16_t v ;
+
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ if (cy_as_device_is_intr_running(dev_p) != 0)
+ return CY_AS_ERROR_ALREADY_RUNNING ;
+
+ v = CY_AS_MEM_P0_INT_MASK_REG_MMCUINT |
+ CY_AS_MEM_P0_INT_MASK_REG_MMBINT |
+ CY_AS_MEM_P0_INT_MASK_REG_MPMINT ;
+
+ if (dmaintr)
+ v |= CY_AS_MEM_P0_INT_MASK_REG_MDRQINT ;
+
+ /* Enable the interrupts of interest */
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, v) ;
+
+ /* Mark the interrupt module as initialized */
+ cy_as_device_set_intr_running(dev_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+uint32_t cy_as_intr_stop(cy_as_device *dev_p)
+{
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ if (cy_as_device_is_intr_running(dev_p) == 0)
+ return CY_AS_ERROR_NOT_RUNNING ;
+
+ cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, 0) ;
+ cy_as_device_set_intr_stopped(dev_p) ;
+
+ return CY_AS_ERROR_SUCCESS ;
+}
+
+void cy_as_intr_service_interrupt(cy_as_hal_device_tag tag)
+{
+ uint16_t v ;
+ cy_as_device *dev_p ;
+
+ dev_p = cy_as_device_find_from_tag(tag) ;
+
+ /*
+ * only power management interrupts can occur before the
+ * antioch API setup is complete. if this is a PM interrupt
+ * handle it here; otherwise output a warning message.
+ */
+ if (dev_p == 0) {
+ v = cy_as_hal_read_register(tag, CY_AS_MEM_P0_INTR_REG) ;
+ if (v == CY_AS_MEM_P0_INTR_REG_PMINT) {
+ /* Read the PWR_MAGT_STAT register
+ * to clear this interrupt. */
+ v = cy_as_hal_read_register(tag,
+ CY_AS_MEM_PWR_MAGT_STAT) ;
+ } else
+ cy_as_hal_print_message("stray antioch "
+ "interrupt detected"
+ ", tag not associated "
+ "with any created device.") ;
+ return ;
+ }
+
+ /* Make sure we got a valid object from CyAsDeviceFindFromTag */
+ cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE) ;
+
+ v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG) ;
+
+ if (v & CY_AS_MEM_P0_INTR_REG_MCUINT)
+ cy_as_mcu_interrupt_handler(dev_p) ;
+
+ if (v & CY_AS_MEM_P0_INTR_REG_PMINT)
+ cy_as_power_management_interrupt_handler(dev_p) ;
+
+ if (v & CY_AS_MEM_P0_INTR_REG_PLLLOCKINT)
+ cy_as_pll_lock_loss_interrupt_handler(dev_p) ;
+
+ /* If the interrupt module is not running, no mailbox
+ * interrupts are expected from the west bridge. */
+ if (cy_as_device_is_intr_running(dev_p) == 0)
+ return ;
+
+ if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
+ cy_as_mail_box_interrupt_handler(dev_p) ;
+}