aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-08-08 21:23:58 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-08-08 21:23:58 -0400
commit8b449d1f1371e8ecd0b2499034e0b1432cdbe662 (patch)
tree56b203189ef65d853f1355abfc65263d96e44a06 /arch
parent2ed9aae0facd603f9f9b8347d1d7e9de23bde286 (diff)
parentee110066130b79b7abf63bbd836d382699252b81 (diff)
Merge remote branch 'gcl/next' into next
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/mpc52xx.h1
-rw-r--r--arch/powerpc/include/asm/mpc52xx_psc.h1
-rw-r--r--arch/powerpc/kernel/setup-common.c2
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c106
4 files changed, 110 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h
index b664ce79a172..1f41382eda38 100644
--- a/arch/powerpc/include/asm/mpc52xx.h
+++ b/arch/powerpc/include/asm/mpc52xx.h
@@ -271,6 +271,7 @@ struct mpc52xx_intr {
271/* mpc52xx_common.c */ 271/* mpc52xx_common.c */
272extern void mpc5200_setup_xlb_arbiter(void); 272extern void mpc5200_setup_xlb_arbiter(void);
273extern void mpc52xx_declare_of_platform_devices(void); 273extern void mpc52xx_declare_of_platform_devices(void);
274extern int mpc5200_psc_ac97_gpio_reset(int psc_number);
274extern void mpc52xx_map_common_devices(void); 275extern void mpc52xx_map_common_devices(void);
275extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); 276extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
276extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); 277extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node);
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h
index ecc4fc69ac13..2966df604221 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -131,6 +131,7 @@
131#define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24) 131#define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24)
132#define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24) 132#define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24)
133#define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24) 133#define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24)
134#define MPC52xx_PSC_SICR_ACRB (0x8 << 24)
134#define MPC52xx_PSC_SICR_AWR (1 << 30) 135#define MPC52xx_PSC_SICR_AWR (1 << 30)
135#define MPC52xx_PSC_SICR_GENCLK (1 << 23) 136#define MPC52xx_PSC_SICR_GENCLK (1 << 23)
136#define MPC52xx_PSC_SICR_I2S (1 << 22) 137#define MPC52xx_PSC_SICR_I2S (1 << 22)
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 15ade0d7bbb2..9d4882a46647 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -96,7 +96,9 @@ struct screen_info screen_info = {
96 96
97/* Variables required to store legacy IO irq routing */ 97/* Variables required to store legacy IO irq routing */
98int of_i8042_kbd_irq; 98int of_i8042_kbd_irq;
99EXPORT_SYMBOL_GPL(of_i8042_kbd_irq);
99int of_i8042_aux_irq; 100int of_i8042_aux_irq;
101EXPORT_SYMBOL_GPL(of_i8042_aux_irq);
100 102
101#ifdef __DO_IRQ_CANON 103#ifdef __DO_IRQ_CANON
102/* XXX should go elsewhere eventually */ 104/* XXX should go elsewhere eventually */
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index a46bad0c2339..6e905314ad5d 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -12,9 +12,11 @@
12 12
13#undef DEBUG 13#undef DEBUG
14 14
15#include <linux/gpio.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/spinlock.h> 17#include <linux/spinlock.h>
17#include <linux/of_platform.h> 18#include <linux/of_platform.h>
19#include <linux/of_gpio.h>
18#include <asm/io.h> 20#include <asm/io.h>
19#include <asm/prom.h> 21#include <asm/prom.h>
20#include <asm/mpc52xx.h> 22#include <asm/mpc52xx.h>
@@ -82,6 +84,14 @@ mpc5200_setup_xlb_arbiter(void)
82 iounmap(xlb); 84 iounmap(xlb);
83} 85}
84 86
87/*
88 * This variable is mapped in mpc52xx_map_common_devices and
89 * used in mpc5200_psc_ac97_gpio_reset().
90 */
91static DEFINE_SPINLOCK(gpio_lock);
92struct mpc52xx_gpio __iomem *simple_gpio;
93struct mpc52xx_gpio_wkup __iomem *wkup_gpio;
94
85/** 95/**
86 * mpc52xx_declare_of_platform_devices: register internal devices and children 96 * mpc52xx_declare_of_platform_devices: register internal devices and children
87 * of the localplus bus to the of_platform 97 * of the localplus bus to the of_platform
@@ -109,6 +119,15 @@ static struct of_device_id mpc52xx_cdm_ids[] __initdata = {
109 { .compatible = "mpc5200-cdm", }, /* old */ 119 { .compatible = "mpc5200-cdm", }, /* old */
110 {} 120 {}
111}; 121};
122static const struct of_device_id mpc52xx_gpio_simple[] = {
123 { .compatible = "fsl,mpc5200-gpio", },
124 {}
125};
126static const struct of_device_id mpc52xx_gpio_wkup[] = {
127 { .compatible = "fsl,mpc5200-gpio-wkup", },
128 {}
129};
130
112 131
113/** 132/**
114 * mpc52xx_map_common_devices: iomap devices required by common code 133 * mpc52xx_map_common_devices: iomap devices required by common code
@@ -135,6 +154,16 @@ mpc52xx_map_common_devices(void)
135 np = of_find_matching_node(NULL, mpc52xx_cdm_ids); 154 np = of_find_matching_node(NULL, mpc52xx_cdm_ids);
136 mpc52xx_cdm = of_iomap(np, 0); 155 mpc52xx_cdm = of_iomap(np, 0);
137 of_node_put(np); 156 of_node_put(np);
157
158 /* simple_gpio registers */
159 np = of_find_matching_node(NULL, mpc52xx_gpio_simple);
160 simple_gpio = of_iomap(np, 0);
161 of_node_put(np);
162
163 /* wkup_gpio registers */
164 np = of_find_matching_node(NULL, mpc52xx_gpio_wkup);
165 wkup_gpio = of_iomap(np, 0);
166 of_node_put(np);
138} 167}
139 168
140/** 169/**
@@ -233,3 +262,80 @@ mpc52xx_restart(char *cmd)
233 262
234 while (1); 263 while (1);
235} 264}
265
266#define PSC1_RESET 0x1
267#define PSC1_SYNC 0x4
268#define PSC1_SDATA_OUT 0x1
269#define PSC2_RESET 0x2
270#define PSC2_SYNC (0x4<<4)
271#define PSC2_SDATA_OUT (0x1<<4)
272#define MPC52xx_GPIO_PSC1_MASK 0x7
273#define MPC52xx_GPIO_PSC2_MASK (0x7<<4)
274
275/**
276 * mpc5200_psc_ac97_gpio_reset: Use gpio pins to reset the ac97 bus
277 *
278 * @psc: psc number to reset (only psc 1 and 2 support ac97)
279 */
280int mpc5200_psc_ac97_gpio_reset(int psc_number)
281{
282 unsigned long flags;
283 u32 gpio;
284 u32 mux;
285 int out;
286 int reset;
287 int sync;
288
289 if ((!simple_gpio) || (!wkup_gpio))
290 return -ENODEV;
291
292 switch (psc_number) {
293 case 0:
294 reset = PSC1_RESET; /* AC97_1_RES */
295 sync = PSC1_SYNC; /* AC97_1_SYNC */
296 out = PSC1_SDATA_OUT; /* AC97_1_SDATA_OUT */
297 gpio = MPC52xx_GPIO_PSC1_MASK;
298 break;
299 case 1:
300 reset = PSC2_RESET; /* AC97_2_RES */
301 sync = PSC2_SYNC; /* AC97_2_SYNC */
302 out = PSC2_SDATA_OUT; /* AC97_2_SDATA_OUT */
303 gpio = MPC52xx_GPIO_PSC2_MASK;
304 break;
305 default:
306 pr_err(__FILE__ ": Unable to determine PSC, no ac97 "
307 "cold-reset will be performed\n");
308 return -ENODEV;
309 }
310
311 spin_lock_irqsave(&gpio_lock, flags);
312
313 /* Reconfiure pin-muxing to gpio */
314 mux = in_be32(&simple_gpio->port_config);
315 out_be32(&simple_gpio->port_config, mux & (~gpio));
316
317 /* enable gpio pins for output */
318 setbits8(&wkup_gpio->wkup_gpioe, reset);
319 setbits32(&simple_gpio->simple_gpioe, sync | out);
320
321 setbits8(&wkup_gpio->wkup_ddr, reset);
322 setbits32(&simple_gpio->simple_ddr, sync | out);
323
324 /* Assert cold reset */
325 clrbits32(&simple_gpio->simple_dvo, sync | out);
326 clrbits8(&wkup_gpio->wkup_dvo, reset);
327
328 /* wait at lease 1 us */
329 udelay(2);
330
331 /* Deassert reset */
332 setbits8(&wkup_gpio->wkup_dvo, reset);
333
334 /* Restore pin-muxing */
335 out_be32(&simple_gpio->port_config, mux);
336
337 spin_unlock_irqrestore(&gpio_lock, flags);
338
339 return 0;
340}
341EXPORT_SYMBOL(mpc5200_psc_ac97_gpio_reset);