diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/boot/dts/mpc885ads.dts | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/8xx/m8xx_setup.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/8xx/mpc885ads_setup.c | 71 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_soc.c | 13 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpc8xx_pic.h | 11 |
5 files changed, 109 insertions, 2 deletions
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts index 110bf617060..aee01087a93 100644 --- a/arch/powerpc/boot/dts/mpc885ads.dts +++ b/arch/powerpc/boot/dts/mpc885ads.dts @@ -112,6 +112,17 @@ compatible = "CPM"; }; + pcmcia@0080 { + #address-cells = <3>; + #interrupt-cells = <1>; + #size-cells = <2>; + compatible = "fsl,pq-pcmcia"; + device_type = "pcmcia"; + reg = <80 80>; + interrupt-parent = <ff000000>; + interrupts = <d 1>; + }; + cpm@ff000000 { linux,phandle = <ff000000>; #address-cells = <1>; diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c index 0901dbada35..f1693550c70 100644 --- a/arch/powerpc/platforms/8xx/m8xx_setup.c +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c @@ -32,6 +32,7 @@ #include <linux/root_dev.h> #include <linux/time.h> #include <linux/rtc.h> +#include <linux/fsl_devices.h> #include <asm/mmu.h> #include <asm/reg.h> @@ -49,6 +50,10 @@ #include "sysdev/mpc8xx_pic.h" +#ifdef CONFIG_PCMCIA_M8XX +struct mpc8xx_pcmcia_ops m8xx_pcmcia_ops; +#endif + void m8xx_calibrate_decr(void); extern void m8xx_wdt_handler_install(bd_t *bp); extern int cpm_pic_init(void); diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c index c36e475d93d..dc27dab48df 100644 --- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c +++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c @@ -22,6 +22,7 @@ #include <linux/fs_enet_pd.h> #include <linux/fs_uart_pd.h> +#include <linux/fsl_devices.h> #include <linux/mii.h> #include <asm/delay.h> @@ -51,6 +52,70 @@ static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi); static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi); static void init_scc3_ioports(struct fs_platform_info* ptr); +#ifdef CONFIG_PCMCIA_M8XX +static void pcmcia_hw_setup(int slot, int enable) +{ + unsigned *bcsr_io; + + bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); + if (enable) + clrbits32(bcsr_io, BCSR1_PCCEN); + else + setbits32(bcsr_io, BCSR1_PCCEN); + + iounmap(bcsr_io); +} + +static int pcmcia_set_voltage(int slot, int vcc, int vpp) +{ + u32 reg = 0; + unsigned *bcsr_io; + + bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); + + switch(vcc) { + case 0: + break; + case 33: + reg |= BCSR1_PCCVCC0; + break; + case 50: + reg |= BCSR1_PCCVCC1; + break; + default: + return 1; + } + + switch(vpp) { + case 0: + break; + case 33: + case 50: + if(vcc == vpp) + reg |= BCSR1_PCCVPP1; + else + return 1; + break; + case 120: + if ((vcc == 33) || (vcc == 50)) + reg |= BCSR1_PCCVPP0; + else + return 1; + default: + return 1; + } + + /* first, turn off all power */ + clrbits32(bcsr_io, 0x00610000); + + /* enable new powersettings */ + setbits32(bcsr_io, reg); + + iounmap(bcsr_io); + return 0; +} +#endif + void __init mpc885ads_board_setup(void) { cpm8xx_t *cp; @@ -115,6 +180,12 @@ void __init mpc885ads_board_setup(void) immr_unmap(io_port); #endif + +#ifdef CONFIG_PCMCIA_M8XX + /*Set up board specific hook-ups*/ + m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup; + m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage; +#endif } diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index cad17572435..c0ddc80d816 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -1028,6 +1028,19 @@ err: arch_initcall(fs_enet_of_init); +static int __init fsl_pcmcia_of_init(void) +{ + struct device_node *np = NULL; + /* + * Register all the devices which type is "pcmcia" + */ + while ((np = of_find_compatible_node(np, + "pcmcia", "fsl,pq-pcmcia")) != NULL) + of_platform_device_create(np, "m8xx-pcmcia", NULL); + return 0; +} + +arch_initcall(fsl_pcmcia_of_init); static const char *smc_regs = "regs"; static const char *smc_pram = "pram"; diff --git a/arch/powerpc/sysdev/mpc8xx_pic.h b/arch/powerpc/sysdev/mpc8xx_pic.h index afa2ee6717c..9fe00eebdc8 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.h +++ b/arch/powerpc/sysdev/mpc8xx_pic.h @@ -4,9 +4,16 @@ #include <linux/irq.h> #include <linux/interrupt.h> -extern struct hw_interrupt_type mpc8xx_pic; - int mpc8xx_pic_init(void); unsigned int mpc8xx_get_irq(void); +/* + * Some internal interrupt registers use an 8-bit mask for the interrupt + * level instead of a number. + */ +static inline uint mk_int_int_mask(uint mask) +{ + return (1 << (7 - (mask/2))); +} + #endif /* _PPC_KERNEL_PPC8xx_H */ |