diff options
Diffstat (limited to 'drivers/clk/at91/clk-usb.c')
-rw-r--r-- | drivers/clk/at91/clk-usb.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 31d5c45e30d7..b0696a928aa9 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -24,6 +24,7 @@ struct at91sam9x5_clk_usb { struct clk_hw hw; struct regmap *regmap; + struct at91_clk_pms pms; u32 usbs_mask; u8 num_parents; }; @@ -148,12 +149,38 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +static int at91sam9x5_usb_save_context(struct clk_hw *hw) +{ + struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); + struct clk_hw *parent_hw = clk_hw_get_parent(hw); + + usb->pms.parent = at91sam9x5_clk_usb_get_parent(hw); + usb->pms.parent_rate = clk_hw_get_rate(parent_hw); + usb->pms.rate = at91sam9x5_clk_usb_recalc_rate(hw, usb->pms.parent_rate); + + return 0; +} + +static void at91sam9x5_usb_restore_context(struct clk_hw *hw) +{ + struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); + int ret; + + ret = at91sam9x5_clk_usb_set_parent(hw, usb->pms.parent); + if (ret) + return; + + at91sam9x5_clk_usb_set_rate(hw, usb->pms.rate, usb->pms.parent_rate); +} + static const struct clk_ops at91sam9x5_usb_ops = { .recalc_rate = at91sam9x5_clk_usb_recalc_rate, .determine_rate = at91sam9x5_clk_usb_determine_rate, .get_parent = at91sam9x5_clk_usb_get_parent, .set_parent = at91sam9x5_clk_usb_set_parent, .set_rate = at91sam9x5_clk_usb_set_rate, + .save_context = at91sam9x5_usb_save_context, + .restore_context = at91sam9x5_usb_restore_context, }; static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) |