linux/drivers/staging/tidspbridge/rmgr/pwr.c
<<
>>
Prefs
   1/*
   2 * pwr.c
   3 *
   4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
   5 *
   6 * PWR API for controlling DSP power states.
   7 *
   8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
   9 *
  10 * This package is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 *
  14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  17 */
  18
  19/*  ----------------------------------- Host OS */
  20#include <dspbridge/host_os.h>
  21
  22/*  ----------------------------------- This */
  23#include <dspbridge/pwr.h>
  24
  25/*  ----------------------------------- Resource Manager */
  26#include <dspbridge/devdefs.h>
  27#include <dspbridge/drv.h>
  28
  29/*  ----------------------------------- Platform Manager */
  30#include <dspbridge/dev.h>
  31
  32/*  ----------------------------------- Link Driver */
  33#include <dspbridge/dspioctl.h>
  34
  35/*
  36 *  ======== pwr_sleep_dsp ========
  37 *    Send command to DSP to enter sleep state.
  38 */
  39int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout)
  40{
  41        struct bridge_drv_interface *intf_fxns;
  42        struct bridge_dev_context *dw_context;
  43        int status = -EPERM;
  44        struct dev_object *hdev_obj = NULL;
  45        u32 ioctlcode = 0;
  46        u32 arg = timeout;
  47
  48        for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
  49             hdev_obj != NULL;
  50             hdev_obj =
  51             (struct dev_object *)drv_get_next_dev_object((u32) hdev_obj)) {
  52                if (dev_get_bridge_context(hdev_obj,
  53                                                (struct bridge_dev_context **)
  54                                                   &dw_context)) {
  55                        continue;
  56                }
  57                if (dev_get_intf_fxns(hdev_obj,
  58                                                (struct bridge_drv_interface **)
  59                                                &intf_fxns)) {
  60                        continue;
  61                }
  62                if (sleep_code == PWR_DEEPSLEEP)
  63                        ioctlcode = BRDIOCTL_DEEPSLEEP;
  64                else if (sleep_code == PWR_EMERGENCYDEEPSLEEP)
  65                        ioctlcode = BRDIOCTL_EMERGENCYSLEEP;
  66                else
  67                        status = -EINVAL;
  68
  69                if (status != -EINVAL) {
  70                        status = (*intf_fxns->pfn_dev_cntrl) (dw_context,
  71                                                              ioctlcode,
  72                                                              (void *)&arg);
  73                }
  74        }
  75        return status;
  76}
  77
  78/*
  79 *  ======== pwr_wake_dsp ========
  80 *    Send command to DSP to wake it from sleep.
  81 */
  82int pwr_wake_dsp(const u32 timeout)
  83{
  84        struct bridge_drv_interface *intf_fxns;
  85        struct bridge_dev_context *dw_context;
  86        int status = -EPERM;
  87        struct dev_object *hdev_obj = NULL;
  88        u32 arg = timeout;
  89
  90        for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
  91             hdev_obj != NULL;
  92             hdev_obj = (struct dev_object *)drv_get_next_dev_object
  93             ((u32) hdev_obj)) {
  94                if (!(dev_get_bridge_context(hdev_obj,
  95                                                      (struct bridge_dev_context
  96                                                       **)&dw_context))) {
  97                        if (!(dev_get_intf_fxns(hdev_obj,
  98                              (struct bridge_drv_interface **)&intf_fxns))) {
  99                                status =
 100                                    (*intf_fxns->pfn_dev_cntrl) (dw_context,
 101                                                        BRDIOCTL_WAKEUP,
 102                                                        (void *)&arg);
 103                        }
 104                }
 105        }
 106        return status;
 107}
 108
 109/*
 110 *  ======== pwr_pm_pre_scale========
 111 *    Sends pre-notification message to DSP.
 112 */
 113int pwr_pm_pre_scale(u16 voltage_domain, u32 level)
 114{
 115        struct bridge_drv_interface *intf_fxns;
 116        struct bridge_dev_context *dw_context;
 117        int status = -EPERM;
 118        struct dev_object *hdev_obj = NULL;
 119        u32 arg[2];
 120
 121        arg[0] = voltage_domain;
 122        arg[1] = level;
 123
 124        for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
 125             hdev_obj != NULL;
 126             hdev_obj = (struct dev_object *)drv_get_next_dev_object
 127             ((u32) hdev_obj)) {
 128                if (!(dev_get_bridge_context(hdev_obj,
 129                                                      (struct bridge_dev_context
 130                                                       **)&dw_context))) {
 131                        if (!(dev_get_intf_fxns(hdev_obj,
 132                              (struct bridge_drv_interface **)&intf_fxns))) {
 133                                status =
 134                                    (*intf_fxns->pfn_dev_cntrl) (dw_context,
 135                                                BRDIOCTL_PRESCALE_NOTIFY,
 136                                                (void *)&arg);
 137                        }
 138                }
 139        }
 140        return status;
 141}
 142
 143/*
 144 *  ======== pwr_pm_post_scale========
 145 *    Sends post-notification message to DSP.
 146 */
 147int pwr_pm_post_scale(u16 voltage_domain, u32 level)
 148{
 149        struct bridge_drv_interface *intf_fxns;
 150        struct bridge_dev_context *dw_context;
 151        int status = -EPERM;
 152        struct dev_object *hdev_obj = NULL;
 153        u32 arg[2];
 154
 155        arg[0] = voltage_domain;
 156        arg[1] = level;
 157
 158        for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
 159             hdev_obj != NULL;
 160             hdev_obj = (struct dev_object *)drv_get_next_dev_object
 161             ((u32) hdev_obj)) {
 162                if (!(dev_get_bridge_context(hdev_obj,
 163                                                      (struct bridge_dev_context
 164                                                       **)&dw_context))) {
 165                        if (!(dev_get_intf_fxns(hdev_obj,
 166                              (struct bridge_drv_interface **)&intf_fxns))) {
 167                                status =
 168                                    (*intf_fxns->pfn_dev_cntrl) (dw_context,
 169                                                BRDIOCTL_POSTSCALE_NOTIFY,
 170                                                (void *)&arg);
 171                        }
 172                }
 173        }
 174        return status;
 175
 176}
 177