aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorVitaly Bordug <vitb@kernel.crashing.org>2007-07-09 14:37:35 -0400
committerKumar Gala <galak@kernel.crashing.org>2007-07-10 01:33:51 -0400
commit80128ff79d282cf71b1819dbca9b8dd47d8ed3e8 (patch)
treec09b48586370aad5bb5d424dea4401778bc1bf2a /arch/powerpc
parent90faf4fa7964a08d36160f7bc3c252866ad1275a (diff)
[POWERPC] 8xx: mpc885ads pcmcia support
Adds support for PowerQuicc on-chip PCMCIA. The driver is implemented as of_device, so only arch/powerpc stuff is capable to use it, which now implies only mpc885ads reference board. To cope with the code that should be hooked inside driver, but is really board specific (like set_voltage), global structure mpc8xx_pcmcia_ops holds necessary function pointers that are filled in the BSP code. [akpm@linux-foundation.org: whitespace diddles] Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org> Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Olof Johansson <olof@lixom.net> Cc: Dominik Brodowski <linux@dominikbrodowski.net> Cc: Paul Mackerras <paulus@samba.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/boot/dts/mpc885ads.dts11
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c5
-rw-r--r--arch/powerpc/platforms/8xx/mpc885ads_setup.c71
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c13
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.h11
5 files changed, 109 insertions, 2 deletions
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 110bf6170603..aee01087a932 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -112,6 +112,17 @@
112 compatible = "CPM"; 112 compatible = "CPM";
113 }; 113 };
114 114
115 pcmcia@0080 {
116 #address-cells = <3>;
117 #interrupt-cells = <1>;
118 #size-cells = <2>;
119 compatible = "fsl,pq-pcmcia";
120 device_type = "pcmcia";
121 reg = <80 80>;
122 interrupt-parent = <ff000000>;
123 interrupts = <d 1>;
124 };
125
115 cpm@ff000000 { 126 cpm@ff000000 {
116 linux,phandle = <ff000000>; 127 linux,phandle = <ff000000>;
117 #address-cells = <1>; 128 #address-cells = <1>;
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 0901dbada350..f1693550c70c 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -32,6 +32,7 @@
32#include <linux/root_dev.h> 32#include <linux/root_dev.h>
33#include <linux/time.h> 33#include <linux/time.h>
34#include <linux/rtc.h> 34#include <linux/rtc.h>
35#include <linux/fsl_devices.h>
35 36
36#include <asm/mmu.h> 37#include <asm/mmu.h>
37#include <asm/reg.h> 38#include <asm/reg.h>
@@ -49,6 +50,10 @@
49 50
50#include "sysdev/mpc8xx_pic.h" 51#include "sysdev/mpc8xx_pic.h"
51 52
53#ifdef CONFIG_PCMCIA_M8XX
54struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops;
55#endif
56
52void m8xx_calibrate_decr(void); 57void m8xx_calibrate_decr(void);
53extern void m8xx_wdt_handler_install(bd_t *bp); 58extern void m8xx_wdt_handler_install(bd_t *bp);
54extern int cpm_pic_init(void); 59extern int cpm_pic_init(void);
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index c36e475d93dc..dc27dab48df0 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/fs_enet_pd.h> 23#include <linux/fs_enet_pd.h>
24#include <linux/fs_uart_pd.h> 24#include <linux/fs_uart_pd.h>
25#include <linux/fsl_devices.h>
25#include <linux/mii.h> 26#include <linux/mii.h>
26 27
27#include <asm/delay.h> 28#include <asm/delay.h>
@@ -51,6 +52,70 @@ static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi);
51static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi); 52static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
52static void init_scc3_ioports(struct fs_platform_info* ptr); 53static void init_scc3_ioports(struct fs_platform_info* ptr);
53 54
55#ifdef CONFIG_PCMCIA_M8XX
56static void pcmcia_hw_setup(int slot, int enable)
57{
58 unsigned *bcsr_io;
59
60 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
61 if (enable)
62 clrbits32(bcsr_io, BCSR1_PCCEN);
63 else
64 setbits32(bcsr_io, BCSR1_PCCEN);
65
66 iounmap(bcsr_io);
67}
68
69static int pcmcia_set_voltage(int slot, int vcc, int vpp)
70{
71 u32 reg = 0;
72 unsigned *bcsr_io;
73
74 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
75
76 switch(vcc) {
77 case 0:
78 break;
79 case 33:
80 reg |= BCSR1_PCCVCC0;
81 break;
82 case 50:
83 reg |= BCSR1_PCCVCC1;
84 break;
85 default:
86 return 1;
87 }
88
89 switch(vpp) {
90 case 0:
91 break;
92 case 33:
93 case 50:
94 if(vcc == vpp)
95 reg |= BCSR1_PCCVPP1;
96 else
97 return 1;
98 break;
99 case 120:
100 if ((vcc == 33) || (vcc == 50))
101 reg |= BCSR1_PCCVPP0;
102 else
103 return 1;
104 default:
105 return 1;
106 }
107
108 /* first, turn off all power */
109 clrbits32(bcsr_io, 0x00610000);
110
111 /* enable new powersettings */
112 setbits32(bcsr_io, reg);
113
114 iounmap(bcsr_io);
115 return 0;
116}
117#endif
118
54void __init mpc885ads_board_setup(void) 119void __init mpc885ads_board_setup(void)
55{ 120{
56 cpm8xx_t *cp; 121 cpm8xx_t *cp;
@@ -115,6 +180,12 @@ void __init mpc885ads_board_setup(void)
115 immr_unmap(io_port); 180 immr_unmap(io_port);
116 181
117#endif 182#endif
183
184#ifdef CONFIG_PCMCIA_M8XX
185 /*Set up board specific hook-ups*/
186 m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup;
187 m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage;
188#endif
118} 189}
119 190
120 191
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index cad175724359..c0ddc80d8160 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1028,6 +1028,19 @@ err:
1028 1028
1029arch_initcall(fs_enet_of_init); 1029arch_initcall(fs_enet_of_init);
1030 1030
1031static int __init fsl_pcmcia_of_init(void)
1032{
1033 struct device_node *np = NULL;
1034 /*
1035 * Register all the devices which type is "pcmcia"
1036 */
1037 while ((np = of_find_compatible_node(np,
1038 "pcmcia", "fsl,pq-pcmcia")) != NULL)
1039 of_platform_device_create(np, "m8xx-pcmcia", NULL);
1040 return 0;
1041}
1042
1043arch_initcall(fsl_pcmcia_of_init);
1031 1044
1032static const char *smc_regs = "regs"; 1045static const char *smc_regs = "regs";
1033static const char *smc_pram = "pram"; 1046static const char *smc_pram = "pram";
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.h b/arch/powerpc/sysdev/mpc8xx_pic.h
index afa2ee6717c1..9fe00eebdc8b 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.h
+++ b/arch/powerpc/sysdev/mpc8xx_pic.h
@@ -4,9 +4,16 @@
4#include <linux/irq.h> 4#include <linux/irq.h>
5#include <linux/interrupt.h> 5#include <linux/interrupt.h>
6 6
7extern struct hw_interrupt_type mpc8xx_pic;
8
9int mpc8xx_pic_init(void); 7int mpc8xx_pic_init(void);
10unsigned int mpc8xx_get_irq(void); 8unsigned int mpc8xx_get_irq(void);
11 9
10/*
11 * Some internal interrupt registers use an 8-bit mask for the interrupt
12 * level instead of a number.
13 */
14static inline uint mk_int_int_mask(uint mask)
15{
16 return (1 << (7 - (mask/2)));
17}
18
12#endif /* _PPC_KERNEL_PPC8xx_H */ 19#endif /* _PPC_KERNEL_PPC8xx_H */