Hi Russell, Thanks for pointing this. I based on pinctrl-armada-xp.c (it needs a fix then, too) and it worked. I must have missed, because I got proper registers' number and values in suspend/resume routines. As pinctrl-armada-xp.c needs also a small fix and in order not to duplicate code, how about a following solution: - *mpp_saved_regs and *mpp_base become members of struct mvebu_pinctrl_soc_info - common mvebu_pinctrl_suspend/resume functions in pinctrl-mvebu.c (now there will be two users AXP and A38X) Please let me know what you think. Best regards, Marcin 2015-10-18 0:29 GMT+02:00 Russell King - ARM Linux <linux@xxxxxxxxxxxxxxxx>: > On Sat, Oct 17, 2015 at 11:28:48PM +0200, Marcin Wojtas wrote: >> diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-38x.c b/drivers/pinctrl/mvebu/pinctrl-armada-38x.c >> index 6ec82c6..094cb48 100644 >> --- a/drivers/pinctrl/mvebu/pinctrl-armada-38x.c >> +++ b/drivers/pinctrl/mvebu/pinctrl-armada-38x.c >> @@ -23,6 +23,7 @@ >> #include "pinctrl-mvebu.h" >> >> static void __iomem *mpp_base; >> +static u32 *mpp_saved_regs; > > I'm not a fan of unnecessary global variables. It adds to the bulk of > the kernel when built-in (even though it's in .bss, it still has a cost) > and these all add up when built-in. > > Please make it part of the driver data allocated at probe time. > >> static int armada_38x_mpp_ctrl_get(unsigned pid, unsigned long *config) >> { >> @@ -424,6 +425,7 @@ static int armada_38x_pinctrl_probe(struct platform_device *pdev) >> const struct of_device_id *match = >> of_match_device(armada_38x_pinctrl_of_match, &pdev->dev); >> struct resource *res; >> + int nregs; >> >> if (!match) >> return -ENODEV; >> @@ -441,11 +443,44 @@ static int armada_38x_pinctrl_probe(struct platform_device *pdev) >> soc->modes = armada_38x_mpp_modes; >> soc->nmodes = armada_38x_mpp_controls[0].npins; >> >> + nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG); >> + >> + mpp_saved_regs = devm_kcalloc(&pdev->dev, nregs, sizeof(u32), >> + GFP_KERNEL); >> + if (!mpp_saved_regs) >> + return -ENOMEM; >> + >> pdev->dev.platform_data = soc; > > The 'soc' is stored in platform data, not driver data, but... > >> >> return mvebu_pinctrl_probe(pdev); >> } >> >> +int armada_38x_pinctrl_suspend(struct platform_device *pdev, pm_message_t state) >> +{ >> + struct mvebu_pinctrl_soc_info *soc = platform_get_drvdata(pdev); > > You access it through driver data. Isn't the driver data here a > struct mvebu_pinctrl pointer? See platform_set_drvdata() in > mvebu_pinctrl_probe(). > >> + int i, nregs; >> + >> + nregs = DIV_ROUND_UP(soc->nmodes, MVEBU_MPPS_PER_REG); >> + >> + for (i = 0; i < nregs; i++) >> + mpp_saved_regs[i] = readl(mpp_base + i * 4); >> + >> + return 0; >> +} >> + >> +int armada_38x_pinctrl_resume(struct platform_device *pdev) >> +{ >> + struct mvebu_pinctrl_soc_info *soc = platform_get_drvdata(pdev); > > Ditto. > > -- > FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up > according to speedtest.net. -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html