/* mid_pmu context structure */
static struct mid_pmu_dev *mid_pmu_cxt;
+static DEFINE_MUTEX(pci_root_lock);
+
/* Accessor function for pci_devs start */
static inline struct pci_dev *get_mid_pci_drv(int lss_index, int i)
{
/* Accessor functions for pci_devs end */
/*
+ * APIs to communicate with pci root,
+ * Returns zero on sucess.
+ */
+int mfld_msg_read32(u32 cmd, u32 *data)
+{
+ struct pci_dev *pci_root;
+ int ret;
+
+ mutex_lock(&pci_root_lock);
+ pci_root = pci_get_bus_and_slot(0, 0);
+
+ ret = pci_write_config_dword(pci_root, PCI_CMD_REG, cmd);
+ if (ret)
+ goto unlock;
+ /*
+ * since we go to unlock with/without error, not
+ * checking for it here
+ */
+ pci_read_config_dword(pci_root, PCI_DATA_REG, data);
+
+unlock:
+ pci_dev_put(pci_root);
+ mutex_unlock(&pci_root_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(mfld_msg_read32);
+
+/*Returns Zero on sucess*/
+int mfld_msg_write32(u32 cmd, u32 data)
+{
+ struct pci_dev *pci_root;
+ int ret;
+
+ mutex_lock(&pci_root_lock);
+ pci_root = pci_get_bus_and_slot(0, 0);
+
+ ret = pci_write_config_dword(pci_root, PCI_DATA_REG, data);
+ if (ret)
+ goto unlock;
+
+ pci_write_config_dword(pci_root, PCI_CMD_REG, cmd);
+
+unlock:
+ pci_dev_put(pci_root);
+ mutex_unlock(&pci_root_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(mfld_msg_write32);
+
+/*
* Locking strategy::
*
* Two semaphores are used to lock the global variables used in
{
int ret;
struct mrst_pmu_reg __iomem *pmu;
+ int cmd;
+ u32 data;
#ifdef CONFIG_HAS_WAKELOCK
wake_lock_init(&mid_pmu_cxt->pmu_wake_lock,
}
/* Map the NC PM registers */
- mid_pmu_cxt->apm_base =
- MDFLD_MSG_READ32(OSPM_PUNIT_PORT, OSPM_APMBA) & 0xffff;
- mid_pmu_cxt->ospm_base =
- MDFLD_MSG_READ32(OSPM_PUNIT_PORT, OSPM_OSPMBA) & 0xffff;
+ cmd = (MSG_READ_CMD << 24) | (OSPM_PUNIT_PORT << 16) |
+ (OSPM_APMBA << 8);
+ if (mfld_msg_read32(cmd, &data)) {
+ ret = PMU_FAILED;
+ goto out_err1;
+ }
+ mid_pmu_cxt->apm_base = data & 0xffff;
+
+ cmd = (MSG_READ_CMD << 24) | (OSPM_PUNIT_PORT << 16) |
+ (OSPM_OSPMBA << 8);
+ if (mfld_msg_read32(cmd, &data)) {
+ ret = PMU_FAILED;
+ goto out_err1;
+ }
+ mid_pmu_cxt->ospm_base = data & 0xffff;
/* Map the memory of pmu1 PMU reg base */
pmu = pci_iomap(dev, 0, 0);
#define APM_CMD 0x0
#define APM_STS 0x04
+#define PCI_CMD_REG 0xD0
+#define PCI_DATA_REG 0xD4
+#define MSG_READ_CMD 0x10
+#define MSG_WRITE_CMD 0x11
enum cm_trigger {
NO_TRIG, /* No trigger is required */
spinlock_t nc_ready_lock;
};
-/*APIs to get the APM base address */
-static inline u32 MDFLD_MSG_READ32(uint port, uint offset)
-{
- int mcr = (0x10<<24) | (port << 16) | (offset << 8);
- uint32_t ret_val = 0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
- pci_write_config_dword(pci_root, 0xD0, mcr);
- pci_read_config_dword(pci_root, 0xD4, &ret_val);
- pci_dev_put(pci_root);
- return ret_val;
-}
-
-static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)
-{
- int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
- pci_write_config_dword(pci_root, 0xD4, value);
- pci_write_config_dword(pci_root, 0xD0, mcr);
- pci_dev_put(pci_root);
-}
-
/* API used to change the platform mode */
extern int pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t state);
extern pci_power_t pmu_pci_choose_state(struct pci_dev *pdev);
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
+#include <linux/errno.h>
+
#ifndef INTEL_MID_PM_H
#define INTEL_MID_PM_H
(int islands, int state_type, int reg_type);
extern void mfld_shutdown(void);
+extern int mfld_msg_read32(u32 cmd, u32 *data);
+extern int mfld_msg_write32(u32 cmd, u32 data);
+
#else
/*
static inline void pmu_set_s0ix_complete(void) { return; }
static inline void mfld_shutdown(void) { return; }
static inline bool pmu_is_s0ix_in_progress(void) { return false; };
+
+/*returns function not implemented*/
+static inline int mfld_msg_read32(u32 cmd, u32 *data) { return -ENOSYS; }
+static inline int mfld_msg_write32(u32 cmd, u32 data) { return -ENOSYS; }
+
#endif /* #ifdef CONFIG_INTEL_MID_POWER */