PageRenderTime 957ms CodeModel.GetById 81ms app.highlight 50ms RepoModel.GetById 72ms app.codeStats 0ms

/drivers/staging/westbridge/astoria/api/src/cyasintr.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 143 lines | 80 code | 30 blank | 33 comment | 18 complexity | a42b3ec087b7fae7871c4c38e027f651 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/* Cypress West Bridge API source file (cyasintr.c)
  2## ===========================
  3## Copyright (C) 2010  Cypress Semiconductor
  4##
  5## This program is free software; you can redistribute it and/or
  6## modify it under the terms of the GNU General Public License
  7## as published by the Free Software Foundation; either version 2
  8## of the License, or (at your option) any later version.
  9##
 10## This program is distributed in the hope that it will be useful,
 11## but WITHOUT ANY WARRANTY; without even the implied warranty of
 12## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13## GNU General Public License for more details.
 14##
 15## You should have received a copy of the GNU General Public License
 16## along with this program; if not, write to the Free Software
 17## Foundation, Inc., 51 Franklin Street, Fifth Floor
 18## Boston, MA  02110-1301, USA.
 19## ===========================
 20*/
 21
 22#include "../../include/linux/westbridge/cyashal.h"
 23#include "../../include/linux/westbridge/cyasdevice.h"
 24#include "../../include/linux/westbridge/cyasregs.h"
 25#include "../../include/linux/westbridge/cyaserr.h"
 26
 27extern void cy_as_mail_box_interrupt_handler(cy_as_device *);
 28
 29void
 30cy_as_mcu_interrupt_handler(cy_as_device *dev_p)
 31{
 32	/* Read and clear the interrupt. */
 33	uint16_t v;
 34
 35	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_MCU_STAT);
 36	v = v;
 37}
 38
 39void
 40cy_as_power_management_interrupt_handler(cy_as_device *dev_p)
 41{
 42	uint16_t v;
 43
 44	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PWR_MAGT_STAT);
 45	v = v;
 46}
 47
 48void
 49cy_as_pll_lock_loss_interrupt_handler(cy_as_device *dev_p)
 50{
 51	uint16_t v;
 52
 53	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PLL_LOCK_LOSS_STAT);
 54	v = v;
 55}
 56
 57uint32_t cy_as_intr_start(cy_as_device *dev_p, cy_bool dmaintr)
 58{
 59	uint16_t v;
 60
 61	cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
 62
 63	if (cy_as_device_is_intr_running(dev_p) != 0)
 64		return CY_AS_ERROR_ALREADY_RUNNING;
 65
 66	v = CY_AS_MEM_P0_INT_MASK_REG_MMCUINT |
 67		CY_AS_MEM_P0_INT_MASK_REG_MMBINT |
 68		CY_AS_MEM_P0_INT_MASK_REG_MPMINT;
 69
 70	if (dmaintr)
 71		v |= CY_AS_MEM_P0_INT_MASK_REG_MDRQINT;
 72
 73	/* Enable the interrupts of interest */
 74	cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, v);
 75
 76	/* Mark the interrupt module as initialized */
 77	cy_as_device_set_intr_running(dev_p);
 78
 79	return CY_AS_ERROR_SUCCESS;
 80}
 81
 82uint32_t cy_as_intr_stop(cy_as_device *dev_p)
 83{
 84	cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
 85
 86	if (cy_as_device_is_intr_running(dev_p) == 0)
 87		return CY_AS_ERROR_NOT_RUNNING;
 88
 89	cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, 0);
 90	cy_as_device_set_intr_stopped(dev_p);
 91
 92	return CY_AS_ERROR_SUCCESS;
 93}
 94
 95void cy_as_intr_service_interrupt(cy_as_hal_device_tag tag)
 96{
 97	uint16_t v;
 98	cy_as_device *dev_p;
 99
100	dev_p = cy_as_device_find_from_tag(tag);
101
102	/*
103	 * only power management interrupts can occur before the
104	 * antioch API setup is complete. if this is a PM interrupt
105	 *  handle it here; otherwise output a warning message.
106	 */
107	if (dev_p == 0) {
108		v = cy_as_hal_read_register(tag, CY_AS_MEM_P0_INTR_REG);
109		if (v == CY_AS_MEM_P0_INTR_REG_PMINT) {
110			/* Read the PWR_MAGT_STAT register
111			 * to clear this interrupt. */
112			v = cy_as_hal_read_register(tag,
113				CY_AS_MEM_PWR_MAGT_STAT);
114		} else
115			cy_as_hal_print_message("stray antioch "
116				"interrupt detected"
117				", tag not associated "
118				"with any created device.");
119		return;
120	}
121
122	/* Make sure we got a valid object from CyAsDeviceFindFromTag */
123	cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);
124
125	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG);
126
127	if (v & CY_AS_MEM_P0_INTR_REG_MCUINT)
128		cy_as_mcu_interrupt_handler(dev_p);
129
130	if (v & CY_AS_MEM_P0_INTR_REG_PMINT)
131		cy_as_power_management_interrupt_handler(dev_p);
132
133	if (v & CY_AS_MEM_P0_INTR_REG_PLLLOCKINT)
134		cy_as_pll_lock_loss_interrupt_handler(dev_p);
135
136	/* If the interrupt module is not running, no mailbox
137	 * interrupts are expected from the west bridge. */
138	if (cy_as_device_is_intr_running(dev_p) == 0)
139		return;
140
141	if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
142		cy_as_mail_box_interrupt_handler(dev_p);
143}