[ARM] 2962/1: scoop: Allow GPIO pin suspend state to be specified

Patch from Richard Purdie

Allow the GPIO pin suspend states to be specified for SCOOP devices.
This is needed for correct operation on the spitz platform.

Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Richard Purdie and committed by Russell King 7c398988 1036260e

+20 -2
+18 -2
arch/arm/common/scoop.c
··· 26 struct scoop_dev { 27 void *base; 28 spinlock_t scoop_lock; 29 u32 scoop_gpwr; 30 }; 31 ··· 92 EXPORT_SYMBOL(read_scoop_reg); 93 EXPORT_SYMBOL(write_scoop_reg); 94 95 #ifdef CONFIG_PM 96 static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level) 97 { 98 if (level == SUSPEND_POWER_DOWN) { 99 struct scoop_dev *sdev = dev_get_drvdata(dev); 100 101 - sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR); 102 - SCOOP_REG(sdev->base,SCOOP_GPWR) = 0; 103 } 104 return 0; 105 } ··· 119 if (level == RESUME_POWER_ON) { 120 struct scoop_dev *sdev = dev_get_drvdata(dev); 121 122 SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; 123 } 124 return 0; ··· 163 reset_scoop(dev); 164 SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; 165 SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; 166 167 return 0; 168 }
··· 26 struct scoop_dev { 27 void *base; 28 spinlock_t scoop_lock; 29 + unsigned short suspend_clr; 30 + unsigned short suspend_set; 31 u32 scoop_gpwr; 32 }; 33 ··· 90 EXPORT_SYMBOL(read_scoop_reg); 91 EXPORT_SYMBOL(write_scoop_reg); 92 93 + static void check_scoop_reg(struct scoop_dev *sdev) 94 + { 95 + unsigned short mcr; 96 + 97 + mcr = SCOOP_REG(sdev->base, SCOOP_MCR); 98 + if ((mcr & 0x100) == 0) 99 + SCOOP_REG(sdev->base, SCOOP_MCR) = 0x0101; 100 + } 101 + 102 #ifdef CONFIG_PM 103 static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level) 104 { 105 if (level == SUSPEND_POWER_DOWN) { 106 struct scoop_dev *sdev = dev_get_drvdata(dev); 107 108 + check_scoop_reg(sdev); 109 + sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR); 110 + SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set; 111 } 112 return 0; 113 } ··· 107 if (level == RESUME_POWER_ON) { 108 struct scoop_dev *sdev = dev_get_drvdata(dev); 109 110 + check_scoop_reg(sdev); 111 SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; 112 } 113 return 0; ··· 150 reset_scoop(dev); 151 SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; 152 SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; 153 + 154 + devptr->suspend_clr = inf->suspend_clr; 155 + devptr->suspend_set = inf->suspend_set; 156 157 return 0; 158 }
+2
include/asm-arm/hardware/scoop.h
··· 38 struct scoop_config { 39 unsigned short io_out; 40 unsigned short io_dir; 41 }; 42 43 /* Structure for linking scoop devices to PCMCIA sockets */
··· 38 struct scoop_config { 39 unsigned short io_out; 40 unsigned short io_dir; 41 + unsigned short suspend_clr; 42 + unsigned short suspend_set; 43 }; 44 45 /* Structure for linking scoop devices to PCMCIA sockets */