Commit c4058b79 authored by Bryan O'Donoghue's avatar Bryan O'Donoghue Committed by Greg Kroah-Hartman

greybus: arche-platform: Rework platform/wd-line state transition logic

This patch simplifies and improves the readability of the internal state
transition logic of arche platform driver state transition logic by:

1. Making a dedicated function to state-transition the platform code.
2. Condense the decision to swtich states down to a single switch
   statement instead of four separate if/else clauses.
Signed-off-by: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Suggested-by: default avatarAlex Elder <elder@linaro.org>
Reviewed-by: default avatarVaibhav Hiremath <vaibhav.hiremath@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 886aba55
...@@ -63,6 +63,13 @@ struct arche_platform_drvdata { ...@@ -63,6 +63,13 @@ struct arche_platform_drvdata {
struct device *dev; struct device *dev;
}; };
/* Requires calling context to hold arche_pdata->spinlock */
static void arche_platform_set_state(struct arche_platform_drvdata *arche_pdata,
enum arche_platform_state state)
{
arche_pdata->state = state;
}
/* /*
* arche_platform_change_state: Change the operational state * arche_platform_change_state: Change the operational state
* *
...@@ -122,22 +129,26 @@ int arche_platform_change_state(enum arche_platform_state state) ...@@ -122,22 +129,26 @@ int arche_platform_change_state(enum arche_platform_state state)
goto exit; goto exit;
} }
if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF || switch (state) {
arche_pdata->state == ARCHE_PLATFORM_STATE_STANDBY || case ARCHE_PLATFORM_STATE_TIME_SYNC:
arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING) {
dev_err(arche_pdata->dev, "busy, request to retry later\n");
goto exit;
}
if (state == ARCHE_PLATFORM_STATE_TIME_SYNC) {
disable_irq(arche_pdata->wake_detect_irq); disable_irq(arche_pdata->wake_detect_irq);
arche_pdata->state = ARCHE_PLATFORM_STATE_TIME_SYNC; break;
} else if (state == ARCHE_PLATFORM_STATE_ACTIVE) { case ARCHE_PLATFORM_STATE_ACTIVE:
arche_pdata->state = ARCHE_PLATFORM_STATE_ACTIVE;
enable_irq(arche_pdata->wake_detect_irq); enable_irq(arche_pdata->wake_detect_irq);
} else { break;
dev_err(arche_pdata->dev, "invalid state transition request\n"); case ARCHE_PLATFORM_STATE_OFF:
case ARCHE_PLATFORM_STATE_STANDBY:
case ARCHE_PLATFORM_STATE_FW_FLASHING:
dev_err(arche_pdata->dev, "busy, request to retry later\n");
goto exit;
default:
ret = -EINVAL;
dev_err(arche_pdata->dev,
"invalid state transition request\n");
goto exit;
} }
arche_platform_set_state(arche_pdata, state);
ret = 0;
exit: exit:
spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
mutex_unlock(&arche_pdata->platform_state_mutex); mutex_unlock(&arche_pdata->platform_state_mutex);
...@@ -146,6 +157,14 @@ int arche_platform_change_state(enum arche_platform_state state) ...@@ -146,6 +157,14 @@ int arche_platform_change_state(enum arche_platform_state state)
} }
EXPORT_SYMBOL_GPL(arche_platform_change_state); EXPORT_SYMBOL_GPL(arche_platform_change_state);
/* Requires arche_pdata->wake_lock is held by calling context */
static void arche_platform_set_wake_detect_state(
struct arche_platform_drvdata *arche_pdata,
enum svc_wakedetect_state state)
{
arche_pdata->wake_detect_state = state;
}
static inline void svc_reset_onoff(unsigned int gpio, bool onoff) static inline void svc_reset_onoff(unsigned int gpio, bool onoff)
{ {
gpio_set_value(gpio, onoff); gpio_set_value(gpio, onoff);
...@@ -208,7 +227,8 @@ static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid) ...@@ -208,7 +227,8 @@ static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
arche_pdata->wake_detect_state = WD_STATE_COLDBOOT_START; arche_platform_set_wake_detect_state(arche_pdata,
WD_STATE_COLDBOOT_START);
spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
/* It should complete power cycle, so first make sure it is poweroff */ /* It should complete power cycle, so first make sure it is poweroff */
...@@ -222,7 +242,7 @@ static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid) ...@@ -222,7 +242,7 @@ static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid)
dev_warn(arche_pdata->dev, "failed to control hub device\n"); dev_warn(arche_pdata->dev, "failed to control hub device\n");
spin_lock_irqsave(&arche_pdata->wake_lock, flags); spin_lock_irqsave(&arche_pdata->wake_lock, flags);
arche_pdata->wake_detect_state = WD_STATE_IDLE; arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);
spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -247,13 +267,14 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid) ...@@ -247,13 +267,14 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid)
if (time_before(jiffies, if (time_before(jiffies,
arche_pdata->wake_detect_start + arche_pdata->wake_detect_start +
msecs_to_jiffies(WD_COLDBOOT_PULSE_WIDTH_MS))) { msecs_to_jiffies(WD_COLDBOOT_PULSE_WIDTH_MS))) {
arche_pdata->wake_detect_state = WD_STATE_IDLE; arche_platform_set_wake_detect_state(arche_pdata,
WD_STATE_IDLE);
} else { } else {
/* Check we are not in middle of irq thread already */ /* Check we are not in middle of irq thread already */
if (arche_pdata->wake_detect_state != if (arche_pdata->wake_detect_state !=
WD_STATE_COLDBOOT_START) { WD_STATE_COLDBOOT_START) {
arche_pdata->wake_detect_state = arche_platform_set_wake_detect_state(arche_pdata,
WD_STATE_COLDBOOT_TRIG; WD_STATE_COLDBOOT_TRIG);
spin_unlock_irqrestore( spin_unlock_irqrestore(
&arche_pdata->wake_lock, &arche_pdata->wake_lock,
flags); flags);
...@@ -270,7 +291,8 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid) ...@@ -270,7 +291,8 @@ static irqreturn_t arche_platform_wd_irq(int irq, void *devid)
* it is meant for coldboot and set the flag. If wake/detect line stays low * it is meant for coldboot and set the flag. If wake/detect line stays low
* beyond 30msec, then it is coldboot else fallback to standby boot. * beyond 30msec, then it is coldboot else fallback to standby boot.
*/ */
arche_pdata->wake_detect_state = WD_STATE_BOOT_INIT; arche_platform_set_wake_detect_state(arche_pdata,
WD_STATE_BOOT_INIT);
} }
} }
...@@ -308,7 +330,7 @@ static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdat ...@@ -308,7 +330,7 @@ static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdat
svc_reset_onoff(arche_pdata->svc_reset_gpio, svc_reset_onoff(arche_pdata->svc_reset_gpio,
!arche_pdata->is_reset_act_hi); !arche_pdata->is_reset_act_hi);
arche_pdata->state = ARCHE_PLATFORM_STATE_ACTIVE; arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_ACTIVE);
return 0; return 0;
} }
...@@ -332,7 +354,7 @@ static void arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_ ...@@ -332,7 +354,7 @@ static void arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_
svc_reset_onoff(arche_pdata->svc_reset_gpio, svc_reset_onoff(arche_pdata->svc_reset_gpio,
!arche_pdata->is_reset_act_hi); !arche_pdata->is_reset_act_hi);
arche_pdata->state = ARCHE_PLATFORM_STATE_FW_FLASHING; arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_FW_FLASHING);
} }
...@@ -353,7 +375,8 @@ static void arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pda ...@@ -353,7 +375,8 @@ static void arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pda
gpio_direction_output(arche_pdata->wake_detect_gpio, 0); gpio_direction_output(arche_pdata->wake_detect_gpio, 0);
usleep_range(100, 200); usleep_range(100, 200);
spin_lock_irqsave(&arche_pdata->wake_lock, flags); spin_lock_irqsave(&arche_pdata->wake_lock, flags);
arche_pdata->wake_detect_state = WD_STATE_IDLE; arche_platform_set_wake_detect_state(arche_pdata,
WD_STATE_IDLE);
spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
clk_disable_unprepare(arche_pdata->svc_ref_clk); clk_disable_unprepare(arche_pdata->svc_ref_clk);
...@@ -363,7 +386,7 @@ static void arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pda ...@@ -363,7 +386,7 @@ static void arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pda
svc_reset_onoff(arche_pdata->svc_reset_gpio, svc_reset_onoff(arche_pdata->svc_reset_gpio,
arche_pdata->is_reset_act_hi); arche_pdata->is_reset_act_hi);
arche_pdata->state = ARCHE_PLATFORM_STATE_OFF; arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);
} }
static ssize_t state_store(struct device *dev, static ssize_t state_store(struct device *dev,
...@@ -502,7 +525,7 @@ static int arche_platform_probe(struct platform_device *pdev) ...@@ -502,7 +525,7 @@ static int arche_platform_probe(struct platform_device *pdev)
dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret); dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret);
return ret; return ret;
} }
arche_pdata->state = ARCHE_PLATFORM_STATE_OFF; arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);
arche_pdata->svc_sysboot_gpio = of_get_named_gpio(np, arche_pdata->svc_sysboot_gpio = of_get_named_gpio(np,
"svc,sysboot-gpio", 0); "svc,sysboot-gpio", 0);
...@@ -567,7 +590,7 @@ static int arche_platform_probe(struct platform_device *pdev) ...@@ -567,7 +590,7 @@ static int arche_platform_probe(struct platform_device *pdev)
} }
/* deassert wake detect */ /* deassert wake detect */
gpio_direction_output(arche_pdata->wake_detect_gpio, 0); gpio_direction_output(arche_pdata->wake_detect_gpio, 0);
arche_pdata->wake_detect_state = WD_STATE_IDLE; arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);
arche_pdata->dev = &pdev->dev; arche_pdata->dev = &pdev->dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment