Commit 18fc64dc authored by Jithu Joseph's avatar Jithu Joseph Committed by Anas Nashif
Browse files

power_mgmt: Sample usage of device_xxx__busy() APIs



To show possible usage of the device_busy_xxx() APIs.
Meant to show how drivers and power policy manager can use them.

Change-Id: I49d1dedd9a7b8d6bf09080c6c7243f0666330941
Signed-off-by: default avatarJithu Joseph <jithu.joseph@intel.com>
parent 592882e5
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -459,6 +459,20 @@ static int i2c_dw_transfer(struct device *dev,
	/* Enable controller */
	regs->ic_enable.bits.enable = 1;

	/*
	 * While waiting at device_sync_call_wait(), kernel can switch to idle
	 * task which in turn can call _sys_soc_suspend() hook of Power
	 * Management App (PMA).
	 * device_busy_set() call here, would indicate to PMA that it should not
	 * execute PM policies that would turn off this ip block, causing an
	 * ongoing hw transaction to be left in an inconsistent state.
	 * Note : This is just a sample to show a possible use of the API, it is
	 * upto the driver expert to see, if he actually needs it here, or
	 * somewhere else, or not needed as the driver's suspend()/resume()
	 * can handle everything
	 */
	device_busy_set(dev);

		/* Process all the messages */
	while (msg_left > 0) {
		pflags = dw->xfr_flags;
@@ -517,6 +531,8 @@ static int i2c_dw_transfer(struct device *dev,
		msg_left--;
	}

	device_busy_clear(dev);

	dw->state = I2C_DW_STATE_READY;

	return ret;
+1 −0
Original line number Diff line number Diff line
@@ -5,3 +5,4 @@ CONFIG_TICKLESS_IDLE=y
CONFIG_RTC=y
CONFIG_GPIO=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_I2C=y
 No newline at end of file
+15 −1
Original line number Diff line number Diff line
@@ -79,9 +79,10 @@ static int check_pm_policy(int32_t ticks)
	 * 0 = no power saving operation
	 * 1 = low power state
	 * 2 = device suspend only
	 * 3 = deep sleep
	 *
	 */
	policy = (policy > 2 ? 0 : policy);
	policy = (policy > 3 ? 0 : policy);

	return policy++;
}
@@ -123,6 +124,15 @@ int _sys_soc_suspend(int32_t ticks)
		start_time = rtc_read(rtc_dev);
		ret = device_suspend_only_entry(ticks);
		break;
	case 3:
		/*
		 * if the policy manager chooses to go to deep sleep, we need to
		 * check if any device is in the middle of a transaction
		 */
		if (!device_any_busy_check()) {
			/* Do deep sleep operations */
			/* break; (fall through for now) */
		}
	default:
		/* No PM operations */
		ret = SYS_PM_NOT_HANDLED;
@@ -190,6 +200,10 @@ static void suspend_devices(int pm_policy)
	for (i = 0; i < device_count; i++) {
		int idx = device_policy_list[i];

		/* If necessary  the policy manager can check if a specific
		 * device in the policy list is busy as shown below :
		 * if(device_busy_check(&device_list[idx])) {do something}
		 */
		device_retval[i] = device_suspend(&device_list[idx], pm_policy);
	}
}