/**
 * resource_test_2 - Tests resource framework APIs when two devices requests
 *                   the same "opp/freq" resource for same or different levels
 * @res_name: Name of the resource requested
 * @req_lvl1: Device 1 level requested for the resource
 * @req_lvl2: Device 2 level requested for the resource
 *
 * Two devices requests the "opp/freq" resource for the specified levels,
 * verifies if the resource's current level is same as the maximum of
 * requested levels and releases the resource
 *
 * Returns 0 on success, -1 on failure
 */
static int resource_test_2(const char *res_name, unsigned long req_lvl1,
			unsigned long req_lvl2)
{
	int ret, result = TEST_PASS;
	int cur_lvl, req_lvl;
	struct device dev1, dev2;

	printk(KERN_INFO "Entry resource_test_2 \n");

	if (!strcmp(res_name, "vdd2_opp"))
		ret = request_vdd2_opp(&dev1, req_lvl1);
	else
		ret = resource_request(res_name, &dev1, req_lvl1);

	if (ret) {
		printk(KERN_ERR "FAILED!!!! dev1 resource request for %s failed"
			" with value %d\n", res_name, ret);
		return TEST_FAIL;
	}

	if (!strcmp(res_name, "vdd2_opp"))
		ret = request_vdd2_opp(&dev2, req_lvl2);
	else
		ret = resource_request(res_name, &dev2, req_lvl2);

	if (ret) {
		printk(KERN_ERR "FAILED!!!! dev2 resource request for %s failed"
			" with value %d\n", res_name, ret);
		resource_release(res_name, &dev1);
		return TEST_FAIL;
	}

	cur_lvl = resource_get_level(res_name);
	req_lvl = (int) max_level(req_lvl1, req_lvl2);
	if (cur_lvl != req_lvl) {
		printk(KERN_ERR "FAILED!!!! resource %s current level:%d"
			" req lvl:%d\n", res_name, cur_lvl, req_lvl);
		result = TEST_FAIL;
	}

	ret = resource_release(res_name, &dev1);
	if (ret) {
		printk(KERN_ERR "FAILED!!!! dev1 resource release for %s failed"
			" with value %d\n", res_name, ret);
		result = TEST_FAIL;
	}
	ret = resource_release(res_name, &dev2);
	if (ret) {
		printk(KERN_ERR "FAILED!!!! dev2 resource release for %s failed"
			" with value %d\n", res_name, ret);
		result = TEST_FAIL;
	}

	if (!result)
		printk(KERN_INFO "resource_test_2 PASSED for %s\n", res_name);
	return result;
}
void omap_pm_vdd1_set_max_opp(struct device *dev, u8 opp_id)
{
	pr_debug("OMAP PM: requests constraint for max OPP ID\n");

	if (opp_id != 0)
		resource_request("vdd1_max", dev, opp_id);
	 else
		resource_request("vdd1_max", dev, MAX_VDD1_OPP);
}
示例#3
0
static void batt_changed(struct power_supply *batt,
			 struct cpcap_batt_data *batt_state)
{
	static char requested;
	int ret = 0;

	if (!batt || !batt_state)
		return;

	if (batt_state->batt_temp < 0) {
		/* To reduce OMAP Vdd1 DC/DC converter output voltage dips as
		 * much as possible, limit Vdd1 to OPP3-OPP5 when the
		 * temperature is below 0 degrees C. */
		if (!requested)
			ret = resource_request("vdd1_opp", batt->dev, VDD1_OPP3);

		if (!ret)
			requested = 1;
	} else if (requested) {
		ret = resource_release("vdd1_opp", batt->dev);

		if (!ret)
			requested = 0;
	}
}
示例#4
0
static void ac_changed(struct power_supply *ac,
		       struct cpcap_batt_ac_data *ac_state)
{
	static char requested;
	int ret = 0;

	if (!ac || !ac_state)
		return;

	if (ac_state->online) {
		/* To reduce OMAP Vdd1 DC/DC converter output voltage dips as
		 * much as possible, limit Vdd1 to OPP3-OPP5 when the phone is
		 * connected to a charger. */
		if (!requested)
			ret = resource_request("vdd1_opp", ac->dev, VDD1_OPP3);

		if (!ret)
			requested = 1;
	} else if (requested) {
		ret = resource_release("vdd1_opp", ac->dev);

		if (!ret)
			requested = 0;
	}
}
/**
 * request_vdd2_opp - resource_request done for vdd2_opp resource
 * @dev: device address
 * @req_lvl: required level
 *
 * does a resource_request for vdd2_opp resource by giving the required
 * throughput input parameter
 *
 * Returns TEST_FAIL during failure or return values of resource_request
 */
static int request_vdd2_opp(struct device *dev, unsigned long req_lvl)
{
	int ret;
	switch (req_lvl) {
	case VDD2_OPP2:
		ret = resource_request("vdd2_opp", dev, VDD2_LEVEL2_THROUGHPUT);
		break;

	case VDD2_OPP3:
		ret = resource_request("vdd2_opp", dev, VDD2_LEVEL3_THROUGHPUT);
		break;

	default:
		printk(KERN_ERR "FAILED!!!! invalid vdd2_opp level\n");
		ret = TEST_FAIL;
	}
	return ret;
}
void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
{
	struct omapdev *odev;
	struct powerdomain *pwrdm_dev;
	struct platform_device *pdev;
	char *lat_res_name;

	if (!dev || t < -1) {
		WARN_ON(1);
		return;
	};
	/* Look for the devices Power Domain */
	/*
	 * WARNING! If device is not a platform device, container_of will
	 * return a pointer to unknown memory!
	 * TODO: Either change omap-pm interface to support only platform
	 * devices, or change the underlying omapdev implementation to
	 * support normal devices.
	 */
	pdev = container_of(dev, struct platform_device, dev);

	/* Try to catch non platform devices. */
	if (pdev->name == NULL) {
		printk(KERN_ERR "OMAP-PM: Error: platform device not valid\n");
		return;
	}

	odev = omapdev_find_pdev(pdev);
	if (odev) {
		pwrdm_dev = omapdev_get_pwrdm(odev);
	} else {
		printk(KERN_ERR "OMAP-PM: Error: Could not find omapdev "
						"for %s\n", pdev->name);
		return;
	}

	lat_res_name = kmalloc(MAX_LATENCY_RES_NAME, GFP_KERNEL);
	if (!lat_res_name) {
		printk(KERN_ERR "OMAP-PM: FATAL ERROR: kmalloc failed\n");
		return;
	}
	get_lat_res_name(pwrdm_dev->name, &lat_res_name, MAX_LATENCY_RES_NAME);

	if (t == -1) {
		pr_debug("OMAP PM: remove max device latency constraint: "
			 "dev %s\n", dev_name(dev));
		resource_release(lat_res_name, dev);
	} else {
		pr_debug("OMAP PM: add max device latency constraint: "
			 "dev %s, t = %ld usec\n", dev_name(dev), t);
		resource_request(lat_res_name, dev, t);
	}

	kfree(lat_res_name);
	return;
}
void omap_pm_cpu_set_freq(unsigned long f)
{
	if (f == 0) {
		WARN_ON(1);
		return;
	}

	pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
		 f);

	resource_request("mpu_freq", &dummy_cpufreq_dev, f);
	return;
}
void omap_pm_set_min_mpu_freq(struct device *dev, unsigned long f)
{
	if (f == 0) {
		WARN_ON(1);
		return;
	}

	pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
		 f);

	resource_request("mpu_freq", dev, f);
	return;
}
示例#9
0
static int hsmmc2_set_power(struct device *dev, int slot, int power_on,
				int vdd)
{
	u32 vdd_sel = 0, devconf = 0;
	int ret = 0;

	if (power_on) {
		if (cpu_is_omap24xx())
			devconf = omap_readl(OMAP2_CONTROL_DEVCONF1);
		else
			devconf = omap_readl(OMAP3_CONTROL_DEVCONF1);

		switch (1 << vdd) {
		case MMC_VDD_33_34:
		case MMC_VDD_32_33:
			vdd_sel = VSEL_3V;
			if (cpu_is_omap24xx())
				devconf = (devconf | (1 << 31));
			break;
		case MMC_VDD_165_195:
			vdd_sel = VSEL_18V;
			if (cpu_is_omap24xx())
				devconf = (devconf & ~(1 << 31));
		}

		if (cpu_is_omap24xx())
			omap_writel(devconf, OMAP2_CONTROL_DEVCONF1);
		else
			omap_writel(devconf | 1 << 6, OMAP3_CONTROL_DEVCONF1);

		ret = resource_request(rhandlemmc2, vdd_sel);
		if (ret != 0)
			goto err;

		return ret;

	} else {
		if (rhandlemmc2 != NULL) {
			ret = resource_release(rhandlemmc2);
			if (ret != 0)
				goto err;
		}
		return ret;
	}
err:
	return 1;
}
/**
 * resource_test_4 - Tests the resource framework basic APIs for
 *                   "latency" resources
 * @res_name: Name of the resource requested
 * @req_lat: Requested lat for the resource
 * @ref_table: Pointer to the reference latency table for the given resource
 *
 * Requests the "latency" resource for the given level,
 * verifies if the resource's current level is same as the
 * closest lower reference level and releases the resource
 *
 * Returns 0 on success, -1 on failure
 */
static int resource_test_4(const char *res_name, unsigned long req_lat,
			unsigned long *ref_table)
{
	int ret, i, result = TEST_PASS;
	int cur_lvl;
	struct device dev;

	printk(KERN_INFO "Entry resource_test_4 \n");

	ret = resource_request(res_name, &dev, req_lat);
	if (ret) {
		printk(KERN_ERR "FAILED!!!! resource request for %s failed"
			" with value %d\n", res_name, ret);
		return TEST_FAIL;
	}

	cur_lvl = resource_get_level(res_name);

	/* using the ref table to find the appropriate PD state */
	for (i = 0; i < 3; i++) {
		if (ref_table[i] < req_lat)
			break;
	}
	if (!enable_off_mode && i == PD_LATENCY_OFF)
		i = PD_LATENCY_RET;
	/* Inactive state is not being tested */
	else if (i == 2)
		i = PD_LATENCY_ON;

	if (cur_lvl != i) {
		printk(KERN_ERR "FAILED!!!! resource %s current level:%d"
			" req lvl:%d\n", res_name, cur_lvl, i);
		result = TEST_FAIL;
	}

	ret = resource_release(res_name, &dev);
	if (ret) {
		printk(KERN_ERR "FAILED!!!! resource release for %s failed"
			" with value %d\n", res_name, ret);
		result = TEST_FAIL;
	}

	if (!result)
		printk(KERN_INFO "resource_test_4 PASSED for %s\n", res_name);
	return result;
}
void omap_pm_dsp_set_min_opp(struct device *dev, unsigned long f)
{
	u8 opp_id;

	if (!dev) {
		WARN_ON(1);
		return;
	};

	pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);

if (cpu_is_omap3630()) {
		/*
		 * check if OPP requested is 65Mz or greater if yes set
		 * max opp constraint to OPP4, Which limits scaling of VDD1
		 * OPP to 1G only. 1.3G will be allowed when DSP load dies
		 * down to 65MHz.
		 */
		if ((f > S65M) && !vdd1_max_opp) {
			vdd1_max_opp = 1;
			omap_pm_vdd1_set_max_opp(dev, VDD1_OPP4);
			omap_pm_vdd1_set_max_opp(dev, VDD1_OPP5);
//			omap_pm_vdd1_set_max_opp(dev, VDD1_OPP6);
		} else if ((f < S260M) && vdd1_max_opp) {
			omap_pm_vdd1_set_max_opp(dev, 0);
			vdd1_max_opp = 0;
		}

		/*
		 * DSP table has 65MHz as OPP5, give OPP1-260MHz when DSP request
		 * 65MHz-OPP1
		 */
		if (f == S65M)
			f = S260M;
//			f = S520M;
	}

	opp_id = get_opp_id(dsp_opps + MAX_VDD1_OPP, f);

	/*
	 * For now pass a dummy_dev struct for SRF to identify the caller.
	 * Maybe its good to have DSP pass this as an argument
	 */
	resource_request("vdd1_opp", dev, opp_id);
	return;
}
void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
{
	if (!dev || t < -1) {
		WARN_ON(1);
		return;
	};

	if (t == -1) {
		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
			 "dev %s\n", dev_name(dev));
		resource_release("mpu_latency", dev);
	} else {
		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
			 "dev %s, t = %ld usec\n", dev_name(dev), t);
		resource_request("mpu_latency", dev, t);
	}
}
void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
{
	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
	    agent_id != OCP_TARGET_AGENT)) {
		WARN_ON(1);
		return;
	};

	if (r == 0) {
		pr_debug("OMAP PM: remove min bus tput constraint: "
			 "dev %s for agent_id %d\n", dev_name(dev), agent_id);
		resource_release("vdd2_opp", dev);
	} else {
		pr_debug("OMAP PM: add min bus tput constraint: "
			 "dev %s for agent_id %d: rate %ld KiB\n",
			 dev_name(dev), agent_id, r);
		resource_request("vdd2_opp", dev, r);
	}
}
示例#14
0
void omap_pm_dsp_set_min_opp(struct device *dev, unsigned long f)
{
	u8 opp_id;

	if (!dev) {
		WARN_ON(1);
		return;
	}

	pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);

	opp_id = get_opp_id(dsp_opps + MAX_VDD1_OPP, f);

	/*
	 * For now pass a dummy_dev struct for SRF to identify the caller.
	 * Maybe its good to have DSP pass this as an argument
	 */
	resource_request("vdd1_opp", dev, opp_id);
	return;
}
示例#15
0
文件: clock.c 项目: mozyg/kernel
/* This function will enable the power for the domain in the which the devices
 * falls. It is called from clk_enable function.  If the device is in PER
 * domain then the power state for PER becomes ON as soon as the first device
 * in PER calls clk_enable.
*/
static int enable_power_domain(struct clk *clk)
{
	char *resource_name;
	u32 domainid;
	u32 ret = 0;
	unsigned short level;

	domainid      = DOMAIN_ID(clk->prcmid);
	resource_name = id_to_name[domainid - 1];

	/* Request for logical resource. Only CORE domain is modelled as a
	 * logical resource.
	 */
	if (resource_name == NULL)
		return ret;

	pr_debug("%s: pwr_domain_name %s name %s\n", __FUNCTION__,
		resource_name, clk->name);

	if (clk->flags & POWER_ON_REQUIRED) {
		if (clk->res == NULL) {
			clk->res = resource_get(clk->name, resource_name);
			if (clk->res == NULL) {
				printk(KERN_ERR"Could not get resource handle"
						"for %s\n", resource_name);
				return -EINVAL;
			}
		}

		level = (!strcmp(resource_name, "core")) ?
					LOGICAL_USED : POWER_DOMAIN_ON;
		ret = resource_request(clk->res, level);
		if (ret) {
			printk(KERN_ERR "Could not request ON for resource %s\n",
							 resource_name);
			return ret;
		}
	}
	return ret;
}
示例#16
0
文件: banker.c 项目: Madsen90/BOSC
/* Threads starts here */
void *process_thread(void *param)
{
  /* Process number */
  int i = (int) (long) param, j;
 
  printf("PROC %d\n", i);
 
  /* Allocate request vector */
  int *request = malloc(n*sizeof(int));
  int q;
  for(q = 0; q < n; q++){
    request[q] = 0;
  }
 
  int legal = 0;
  while (1) {
   
    /* Generate request */
    generate_request(i, request);
 
    while (!resource_request(i, request)) {
      printf("%s\n", "Waiting");
      /* Wait */
      Sleep(1000);
    }
   
 
 
 
    /* Generate release */
    generate_release(i, request);
    /* Release resources */
    resource_release(i, request);
    /* Wait */
 
    Sleep(1000);
  }
  free(request);
}
示例#17
0
文件: banker.c 项目: Jelb/BOSC
/* Threads starts here */
void *process_thread(void *param)
{
    /* Process number */
    int i = (int) (long) param, j;
    /* Allocate request vector */
    int *request = malloc(n*sizeof(int));
    while (1) {
        /* Generate request */
        generate_request(i, request);
        while (!resource_request(i, request)) {
            /* Wait */
            Sleep(100);
        }
        /* Generate release */
        generate_release(i, request);
        /* Release resources */
        resource_release(i, request);
        /* Wait */
        Sleep(1000);
    }
    free(request);
}
示例#18
0
void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
{
#if 1 // Archer-Froyo, KERNEL PANIC in update_resource_level() after EnableSGXClocks()  	
    return; 
#endif // Archer-Froyo 
 	
	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
	    agent_id != OCP_TARGET_AGENT)) {
		WARN_ON(1);
		return;
	};

	if (r == 0) {
		pr_debug("OMAP PM: remove min bus tput constraint: "
			 "dev %s for agent_id %d\n", dev_name(dev), agent_id);
		resource_release("vdd2_opp", dev);
	} else {
		pr_debug("OMAP PM: add min bus tput constraint: "
			 "dev %s for agent_id %d: rate %ld KiB\n",
			 dev_name(dev), agent_id, r);
		resource_request("vdd2_opp", dev, r);
	}
}
/**
 * resource_test_7 - Tests the resource_refresh API
 * @res_name: Name of the resource requested ("vdd1_opp"/"vdd2_opp")
 * @req_lvl1: Requested lower level for the resource
 * @req_lvl2: Requested higher level for the resource
 *
 * Device 1 requests the resource for the given lower level,
 * locks the resource. Meanwhile device 2 requests the reource for a
 * higher level.
 * Verifies if the resource's current level is same as the requested
 * higher level after device 1 unlocks the resource
 *
 * Returns 0 on success, -1 on failure
 */
static int resource_test_7(const char *res_name, unsigned long req_lvl1,
			unsigned long req_lvl2)
{
	int ret, cur_lvl, result = TEST_PASS;
	int lock_val;
	struct device dev1, dev2;

	printk(KERN_INFO "Entry resource_test_7 \n");

	if (!strcmp(res_name, "vdd1_opp"))
		lock_val = VDD1_OPP;
	else if (!strcmp(res_name, "vdd2_opp"))
		lock_val = VDD2_OPP;
	else {
		printk(KERN_ERR "FAILED!!!! invalid resource name\n");
		return TEST_FAIL;
	}

	ret = resource_request(res_name, &dev1, req_lvl1);
	if (ret) {
		printk(KERN_ERR "FAILED!!!! resource1 request for %s failed"
			" with value %d\n", res_name, ret);
		return TEST_FAIL;
	}

	cur_lvl = resource_get_level(res_name);
	if (cur_lvl != req_lvl1) {
		printk(KERN_ERR "FAILED!!!! resource %s current level:%d"
			" req lvl:%d\n", res_name, cur_lvl, (int)req_lvl1);
		result = TEST_FAIL;
	}

	if (result == TEST_PASS) {
		ret = resource_access_opp_lock(lock_val, 1);
		if (ret < 0) {
			printk(KERN_ERR "FAILED!!!! resource %s lock failed"
				" with value %d\n", res_name, ret);
			result = TEST_FAIL;
		}
	}

	if (result == TEST_PASS) {
		ret = resource_request(res_name, &dev2, req_lvl2);
		if (ret) {
			printk(KERN_ERR "FAILED!!!! resource2 request %s failed"
				" with value %d\n", res_name, ret);
			ret = resource_access_opp_lock(lock_val, -1);
			if (ret < 0)
				printk(KERN_ERR "FAILED!!!! resource unlock"
					"for %s failed\n", res_name);
			result = TEST_FAIL;
		}
	}

	if (result == TEST_PASS) {
		cur_lvl = resource_get_level(res_name);
		if (cur_lvl != req_lvl1) {
			printk(KERN_ERR "FAILED!!!! %s current level:%d"
				" req lvl:%d\n", res_name, cur_lvl,
				(int)req_lvl1);
			result = TEST_FAIL;
		}

		ret = resource_access_opp_lock(lock_val, -1);
		if (ret < 0) {
			printk(KERN_ERR "FAILED!!!! resource unlock %s failed"
				" with value %d\n", res_name, ret);
			result = TEST_FAIL;
		}

		ret = resource_refresh();
		if (ret) {
			printk(KERN_ERR "FAILED!!!! resource refresh failed"
				" with value %d\n", ret);
			result = TEST_FAIL;
		}

		cur_lvl = resource_get_level(res_name);
		if (cur_lvl != req_lvl2) {
			printk(KERN_ERR "FAILED!!!! %s current level:%d"
				" req lvl:%d\n", res_name, cur_lvl,
				(int)req_lvl2);
			result = TEST_FAIL;
		}
	}

	ret = resource_release(res_name, &dev1);
	if (ret) {
		printk(KERN_ERR "FAILED!!!! resource1 release for %s failed"
			" with value %d\n", res_name, ret);
		result = TEST_FAIL;
	}
	ret = resource_release(res_name, &dev2);
	if (ret) {
		printk(KERN_ERR "FAILED!!!! resource2 release for %s failed"
			" with value %d\n", res_name, ret);
		result = TEST_FAIL;
	}

	if (!result)
		printk(KERN_INFO "resource_test_7 PASSED for %s\n", res_name);
	return result;
}
示例#20
0
static int hsmmc_set_power(struct device *dev, int slot, int power_on,
				int vdd)
{
	u32 vdd_sel = 0, devconf = 0, reg = 0;
	int ret = 0;

	/* REVISIT: Using address directly till the control.h defines
	 * are settled.
	 */
#if defined(CONFIG_ARCH_OMAP2430)
	#define OMAP2_CONTROL_PBIAS 0x490024A0
#else
	#define OMAP2_CONTROL_PBIAS 0x48002520
#endif

	if (power_on) {
		if (cpu_is_omap24xx())
			devconf = omap_readl(OMAP2_CONTROL_DEVCONF1);
		else
			devconf = omap_readl(OMAP3_CONTROL_DEVCONF0);

		switch (1 << vdd) {
		case MMC_VDD_33_34:
		case MMC_VDD_32_33:
			vdd_sel = VSEL_3V;
			if (cpu_is_omap24xx())
				devconf |= OMAP2_CONTROL_DEVCONF1_ACTOV;
			break;
		case MMC_VDD_165_195:
			vdd_sel = VSEL_18V;
			if (cpu_is_omap24xx())
				devconf &= ~OMAP2_CONTROL_DEVCONF1_ACTOV;
		}

		if (cpu_is_omap24xx())
			omap_writel(devconf, OMAP2_CONTROL_DEVCONF1);
		else
			omap_writel(devconf | OMAP2_CONTROL_DEVCONF0_LBCLK,
				    OMAP3_CONTROL_DEVCONF0);

		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg |= OMAP2_CONTROL_PBIAS_SCTRL;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg |= OMAP2_CONTROL_PBIAS_SCTRL1;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ1;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		ret = resource_request(rhandlemmc1, (vdd_sel == VSEL_3V ?
			T2_VMMC1_3V00 : T2_VMMC1_1V85));
		if (ret != 0)
			goto err;

		/* Enable VSIM to support MMC 8-bit on ES2 */
		if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
			ret = resource_request(rhandlevsim,
				(vdd_sel == VSEL_3V ?
				T2_VSIM_3V00 : T2_VSIM_1V80));
			if (ret != 0)
				return ret;
		}
		msleep(100);
		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg = (vdd_sel == VSEL_18V) ?
			(((reg | 0x0606) & ~0x1) & ~(1<<8))
			: (reg | 0x0707);
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		return ret;

	} else {
		/* Power OFF */

		/* For MMC1, Toggle PBIAS before every power up sequence */
		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ;
		omap_writel(reg, OMAP2_CONTROL_PBIAS);

		if (rhandlemmc1 != NULL) {
			ret = resource_release(rhandlemmc1);
			if (ret != 0)
				goto err;
		}

		if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)
					 && (rhandlevsim != NULL)) {
			ret = resource_release(rhandlevsim);
			if (ret != 0)
				goto err;
		}

		if (is_sil_rev_equal_to(OMAP3430_REV_ES3_0)) {
			ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
				LDO_CLR, VSIM_DEV_GRP);
			if (ret)
				goto err;
			ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
				LDO_CLR, VSIM_DEDICATED);
			if (ret)
				goto err;
		}

		/* 100ms delay required for PBIAS configuration */
		msleep(100);
		reg = omap_readl(OMAP2_CONTROL_PBIAS);
		reg |= (OMAP2_CONTROL_PBIAS_VMODE |
			OMAP2_CONTROL_PBIAS_VMODE1 |
			OMAP2_CONTROL_PBIAS_PWRDNZ |
			OMAP2_CONTROL_PBIAS_PWRDNZ1 |
			OMAP2_CONTROL_PBIAS_SCTRL |
			OMAP2_CONTROL_PBIAS_SCTRL1);
		omap_writel(reg, OMAP2_CONTROL_PBIAS);
	}

	return 0;

err:
	return 1;
}