aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-ml-ioh.c
diff options
context:
space:
mode:
authorTomoya MORINAGA <tomoya-linux@dsn.okisemi.com>2011-08-05 00:04:22 -0400
committerGrant Likely <grant.likely@secretlab.ca>2011-10-05 13:57:04 -0400
commitb490fa0bf86edbc06562024cbace5e84f0e2cf0e (patch)
treeec44b535b6fab56c2aee9973cbc38b1f61b52fb1 /drivers/gpio/gpio-ml-ioh.c
parent54be566317b6aece2389a95bb19ea209af9359be (diff)
gpio-ml-ioh: Fix suspend/resume issue
Currently, some registers are not saved in case changing to suspend state. This patch fixes the issue. Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio/gpio-ml-ioh.c')
-rw-r--r--drivers/gpio/gpio-ml-ioh.c60
1 files changed, 48 insertions, 12 deletions
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c
index 4fab37bf564d..274fd4d0792f 100644
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -63,6 +63,7 @@ struct ioh_regs {
63 * @pm_reg: To store contents of PM register. 63 * @pm_reg: To store contents of PM register.
64 * @im0_reg: To store contents of interrupt mode regist0 64 * @im0_reg: To store contents of interrupt mode regist0
65 * @im1_reg: To store contents of interrupt mode regist1 65 * @im1_reg: To store contents of interrupt mode regist1
66 * @use_sel_reg: To store contents of GPIO_USE_SEL0~3
66 */ 67 */
67struct ioh_gpio_reg_data { 68struct ioh_gpio_reg_data {
68 u32 ien_reg; 69 u32 ien_reg;
@@ -71,6 +72,7 @@ struct ioh_gpio_reg_data {
71 u32 pm_reg; 72 u32 pm_reg;
72 u32 im0_reg; 73 u32 im0_reg;
73 u32 im1_reg; 74 u32 im1_reg;
75 u32 use_sel_reg;
74}; 76};
75 77
76/** 78/**
@@ -81,6 +83,7 @@ struct ioh_gpio_reg_data {
81 * @gpio: Data for GPIO infrastructure. 83 * @gpio: Data for GPIO infrastructure.
82 * @ioh_gpio_reg: Memory mapped Register data is saved here 84 * @ioh_gpio_reg: Memory mapped Register data is saved here
83 * when suspend. 85 * when suspend.
86 * @gpio_use_sel: Save GPIO_USE_SEL1~4 register for PM
84 * @ch: Indicate GPIO channel 87 * @ch: Indicate GPIO channel
85 * @irq_base: Save base of IRQ number for interrupt 88 * @irq_base: Save base of IRQ number for interrupt
86 * @spinlock: Used for register access protection in 89 * @spinlock: Used for register access protection in
@@ -92,6 +95,7 @@ struct ioh_gpio {
92 struct device *dev; 95 struct device *dev;
93 struct gpio_chip gpio; 96 struct gpio_chip gpio;
94 struct ioh_gpio_reg_data ioh_gpio_reg; 97 struct ioh_gpio_reg_data ioh_gpio_reg;
98 u32 gpio_use_sel;
95 struct mutex lock; 99 struct mutex lock;
96 int ch; 100 int ch;
97 int irq_base; 101 int irq_base;
@@ -169,12 +173,25 @@ static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
169 */ 173 */
170static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) 174static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip)
171{ 175{
172 chip->ioh_gpio_reg.po_reg = ioread32(&chip->reg->regs[chip->ch].po); 176 int i;
173 chip->ioh_gpio_reg.pm_reg = ioread32(&chip->reg->regs[chip->ch].pm); 177
174 chip->ioh_gpio_reg.ien_reg = ioread32(&chip->reg->regs[chip->ch].ien); 178 for (i = 0; i < 8; i ++, chip++) {
175 chip->ioh_gpio_reg.imask_reg = ioread32(&chip->reg->regs[chip->ch].imask); 179 chip->ioh_gpio_reg.po_reg =
176 chip->ioh_gpio_reg.im0_reg = ioread32(&chip->reg->regs[chip->ch].im_0); 180 ioread32(&chip->reg->regs[chip->ch].po);
177 chip->ioh_gpio_reg.im1_reg = ioread32(&chip->reg->regs[chip->ch].im_1); 181 chip->ioh_gpio_reg.pm_reg =
182 ioread32(&chip->reg->regs[chip->ch].pm);
183 chip->ioh_gpio_reg.ien_reg =
184 ioread32(&chip->reg->regs[chip->ch].ien);
185 chip->ioh_gpio_reg.imask_reg =
186 ioread32(&chip->reg->regs[chip->ch].imask);
187 chip->ioh_gpio_reg.im0_reg =
188 ioread32(&chip->reg->regs[chip->ch].im_0);
189 chip->ioh_gpio_reg.im1_reg =
190 ioread32(&chip->reg->regs[chip->ch].im_1);
191 if (i < 4)
192 chip->ioh_gpio_reg.use_sel_reg =
193 ioread32(&chip->reg->ioh_sel_reg[i]);
194 }
178} 195}
179 196
180/* 197/*
@@ -182,12 +199,25 @@ static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip)
182 */ 199 */
183static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) 200static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip)
184{ 201{
185 iowrite32(chip->ioh_gpio_reg.po_reg, &chip->reg->regs[chip->ch].po); 202 int i;
186 iowrite32(chip->ioh_gpio_reg.pm_reg, &chip->reg->regs[chip->ch].pm); 203
187 iowrite32(chip->ioh_gpio_reg.ien_reg, &chip->reg->regs[chip->ch].ien); 204 for (i = 0; i < 8; i ++, chip++) {
188 iowrite32(chip->ioh_gpio_reg.imask_reg, &chip->reg->regs[chip->ch].imask); 205 iowrite32(chip->ioh_gpio_reg.po_reg,
189 iowrite32(chip->ioh_gpio_reg.im0_reg, &chip->reg->regs[chip->ch].im_0); 206 &chip->reg->regs[chip->ch].po);
190 iowrite32(chip->ioh_gpio_reg.im1_reg, &chip->reg->regs[chip->ch].im_1); 207 iowrite32(chip->ioh_gpio_reg.pm_reg,
208 &chip->reg->regs[chip->ch].pm);
209 iowrite32(chip->ioh_gpio_reg.ien_reg,
210 &chip->reg->regs[chip->ch].ien);
211 iowrite32(chip->ioh_gpio_reg.imask_reg,
212 &chip->reg->regs[chip->ch].imask);
213 iowrite32(chip->ioh_gpio_reg.im0_reg,
214 &chip->reg->regs[chip->ch].im_0);
215 iowrite32(chip->ioh_gpio_reg.im1_reg,
216 &chip->reg->regs[chip->ch].im_1);
217 if (i < 4)
218 iowrite32(chip->ioh_gpio_reg.use_sel_reg,
219 &chip->reg->ioh_sel_reg[i]);
220 }
191} 221}
192#endif 222#endif
193 223
@@ -485,8 +515,11 @@ static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state)
485{ 515{
486 s32 ret; 516 s32 ret;
487 struct ioh_gpio *chip = pci_get_drvdata(pdev); 517 struct ioh_gpio *chip = pci_get_drvdata(pdev);
518 unsigned long flags;
488 519
520 spin_lock_irqsave(&chip->spinlock, flags);
489 ioh_gpio_save_reg_conf(chip); 521 ioh_gpio_save_reg_conf(chip);
522 spin_unlock_irqrestore(&chip->spinlock, flags);
490 523
491 ret = pci_save_state(pdev); 524 ret = pci_save_state(pdev);
492 if (ret) { 525 if (ret) {
@@ -506,6 +539,7 @@ static int ioh_gpio_resume(struct pci_dev *pdev)
506{ 539{
507 s32 ret; 540 s32 ret;
508 struct ioh_gpio *chip = pci_get_drvdata(pdev); 541 struct ioh_gpio *chip = pci_get_drvdata(pdev);
542 unsigned long flags;
509 543
510 ret = pci_enable_wake(pdev, PCI_D0, 0); 544 ret = pci_enable_wake(pdev, PCI_D0, 0);
511 545
@@ -517,9 +551,11 @@ static int ioh_gpio_resume(struct pci_dev *pdev)
517 } 551 }
518 pci_restore_state(pdev); 552 pci_restore_state(pdev);
519 553
554 spin_lock_irqsave(&chip->spinlock, flags);
520 iowrite32(0x01, &chip->reg->srst); 555 iowrite32(0x01, &chip->reg->srst);
521 iowrite32(0x00, &chip->reg->srst); 556 iowrite32(0x00, &chip->reg->srst);
522 ioh_gpio_restore_reg_conf(chip); 557 ioh_gpio_restore_reg_conf(chip);
558 spin_unlock_irqrestore(&chip->spinlock, flags);
523 559
524 return 0; 560 return 0;
525} 561}