mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 18:54:09 +08:00
Merge branch 'fixes' of git://github.com/hzhuang1/linux into fixes
* 'fixes' of git://github.com/hzhuang1/linux: ARM: PXA2xx: MFP: fix potential direction bug ARM: PXA2xx: MFP: fix bug with MFP_LPM_KEEP_OUTPUT arm/sa1100: fix sa1100-rtc memory resource ARM: pxa: fix gpio wakeup setting
This commit is contained in:
commit
dadb3660a3
@ -17,6 +17,7 @@
|
||||
*
|
||||
* bit 23 - Input/Output (PXA2xx specific)
|
||||
* bit 24 - Wakeup Enable(PXA2xx specific)
|
||||
* bit 25 - Keep Output (PXA2xx specific)
|
||||
*/
|
||||
|
||||
#define MFP_DIR_IN (0x0 << 23)
|
||||
@ -25,6 +26,12 @@
|
||||
#define MFP_DIR(x) (((x) >> 23) & 0x1)
|
||||
|
||||
#define MFP_LPM_CAN_WAKEUP (0x1 << 24)
|
||||
|
||||
/*
|
||||
* MFP_LPM_KEEP_OUTPUT must be specified for pins that need to
|
||||
* retain their last output level (low or high).
|
||||
* Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input.
|
||||
*/
|
||||
#define MFP_LPM_KEEP_OUTPUT (0x1 << 25)
|
||||
|
||||
#define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE)
|
||||
|
@ -33,6 +33,8 @@
|
||||
#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
|
||||
#define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5))
|
||||
#define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c)
|
||||
#define GPSR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18)
|
||||
#define GPCR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24)
|
||||
|
||||
#define PWER_WE35 (1 << 24)
|
||||
|
||||
@ -348,6 +350,7 @@ static inline void pxa27x_mfp_init(void) {}
|
||||
#ifdef CONFIG_PM
|
||||
static unsigned long saved_gafr[2][4];
|
||||
static unsigned long saved_gpdr[4];
|
||||
static unsigned long saved_gplr[4];
|
||||
static unsigned long saved_pgsr[4];
|
||||
|
||||
static int pxa2xx_mfp_suspend(void)
|
||||
@ -366,14 +369,26 @@ static int pxa2xx_mfp_suspend(void)
|
||||
}
|
||||
|
||||
for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
|
||||
|
||||
saved_gafr[0][i] = GAFR_L(i);
|
||||
saved_gafr[1][i] = GAFR_U(i);
|
||||
saved_gpdr[i] = GPDR(i * 32);
|
||||
saved_gplr[i] = GPLR(i * 32);
|
||||
saved_pgsr[i] = PGSR(i);
|
||||
|
||||
GPDR(i * 32) = gpdr_lpm[i];
|
||||
GPSR(i * 32) = PGSR(i);
|
||||
GPCR(i * 32) = ~PGSR(i);
|
||||
}
|
||||
|
||||
/* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */
|
||||
for (i = 0; i < pxa_last_gpio; i++) {
|
||||
if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) ||
|
||||
((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
|
||||
(saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i))))
|
||||
GPDR(i) |= GPIO_bit(i);
|
||||
else
|
||||
GPDR(i) &= ~GPIO_bit(i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -384,6 +399,8 @@ static void pxa2xx_mfp_resume(void)
|
||||
for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
|
||||
GAFR_L(i) = saved_gafr[0][i];
|
||||
GAFR_U(i) = saved_gafr[1][i];
|
||||
GPSR(i * 32) = saved_gplr[i];
|
||||
GPCR(i * 32) = ~saved_gplr[i];
|
||||
GPDR(i * 32) = saved_gpdr[i];
|
||||
PGSR(i) = saved_pgsr[i];
|
||||
}
|
||||
|
@ -421,8 +421,11 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
|
||||
pxa_register_device(&pxa27x_device_i2c_power, info);
|
||||
}
|
||||
|
||||
static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = {
|
||||
.gpio_set_wake = gpio_set_wake,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&pxa_device_gpio,
|
||||
&pxa27x_device_udc,
|
||||
&pxa_device_pmu,
|
||||
&pxa_device_i2s,
|
||||
@ -458,6 +461,7 @@ static int __init pxa27x_init(void)
|
||||
register_syscore_ops(&pxa2xx_mfp_syscore_ops);
|
||||
register_syscore_ops(&pxa2xx_clock_syscore_ops);
|
||||
|
||||
pxa_register_device(&pxa_device_gpio, &pxa27x_gpio_info);
|
||||
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
|
||||
|
@ -306,7 +306,7 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
|
||||
}
|
||||
|
||||
static struct resource sa1100_rtc_resources[] = {
|
||||
DEFINE_RES_MEM(0x90010000, 0x9001003f),
|
||||
DEFINE_RES_MEM(0x90010000, 0x40),
|
||||
DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
|
||||
DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
|
||||
};
|
||||
|
@ -64,6 +64,7 @@ struct pxa_gpio_chip {
|
||||
unsigned long irq_mask;
|
||||
unsigned long irq_edge_rise;
|
||||
unsigned long irq_edge_fall;
|
||||
int (*set_wake)(unsigned int gpio, unsigned int on);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
unsigned long saved_gplr;
|
||||
@ -269,7 +270,8 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
(value ? GPSR_OFFSET : GPCR_OFFSET));
|
||||
}
|
||||
|
||||
static int __devinit pxa_init_gpio_chip(int gpio_end)
|
||||
static int __devinit pxa_init_gpio_chip(int gpio_end,
|
||||
int (*set_wake)(unsigned int, unsigned int))
|
||||
{
|
||||
int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
|
||||
struct pxa_gpio_chip *chips;
|
||||
@ -285,6 +287,7 @@ static int __devinit pxa_init_gpio_chip(int gpio_end)
|
||||
|
||||
sprintf(chips[i].label, "gpio-%d", i);
|
||||
chips[i].regbase = gpio_reg_base + BANK_OFF(i);
|
||||
chips[i].set_wake = set_wake;
|
||||
|
||||
c->base = gpio;
|
||||
c->label = chips[i].label;
|
||||
@ -412,6 +415,17 @@ static void pxa_mask_muxed_gpio(struct irq_data *d)
|
||||
writel_relaxed(gfer, c->regbase + GFER_OFFSET);
|
||||
}
|
||||
|
||||
static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on)
|
||||
{
|
||||
int gpio = pxa_irq_to_gpio(d->irq);
|
||||
struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
|
||||
|
||||
if (c->set_wake)
|
||||
return c->set_wake(gpio, on);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pxa_unmask_muxed_gpio(struct irq_data *d)
|
||||
{
|
||||
int gpio = pxa_irq_to_gpio(d->irq);
|
||||
@ -427,6 +441,7 @@ static struct irq_chip pxa_muxed_gpio_chip = {
|
||||
.irq_mask = pxa_mask_muxed_gpio,
|
||||
.irq_unmask = pxa_unmask_muxed_gpio,
|
||||
.irq_set_type = pxa_gpio_irq_type,
|
||||
.irq_set_wake = pxa_gpio_set_wake,
|
||||
};
|
||||
|
||||
static int pxa_gpio_nums(void)
|
||||
@ -471,6 +486,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)
|
||||
struct pxa_gpio_chip *c;
|
||||
struct resource *res;
|
||||
struct clk *clk;
|
||||
struct pxa_gpio_platform_data *info;
|
||||
int gpio, irq, ret;
|
||||
int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
|
||||
|
||||
@ -516,7 +532,8 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Initialize GPIO chips */
|
||||
pxa_init_gpio_chip(pxa_last_gpio);
|
||||
info = dev_get_platdata(&pdev->dev);
|
||||
pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);
|
||||
|
||||
/* clear all GPIO edge detects */
|
||||
for_each_gpio_chip(gpio, c) {
|
||||
|
@ -13,4 +13,8 @@ extern int pxa_last_gpio;
|
||||
|
||||
extern int pxa_irq_to_gpio(int irq);
|
||||
|
||||
struct pxa_gpio_platform_data {
|
||||
int (*gpio_set_wake)(unsigned int gpio, unsigned int on);
|
||||
};
|
||||
|
||||
#endif /* __GPIO_PXA_H */
|
||||
|
Loading…
Reference in New Issue
Block a user