Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
0007  */
0008 
0009 #include <linux/init.h>
0010 #include <linux/kernel.h>
0011 #include <asm/bootinfo.h>
0012 #include <linux/platform_device.h>
0013 #include <bcm63xx_cs.h>
0014 #include <bcm63xx_cpu.h>
0015 #include <bcm63xx_dev_pcmcia.h>
0016 #include <bcm63xx_io.h>
0017 #include <bcm63xx_regs.h>
0018 
0019 static struct resource pcmcia_resources[] = {
0020     /* pcmcia registers */
0021     {
0022         /* start & end filled at runtime */
0023         .flags      = IORESOURCE_MEM,
0024     },
0025 
0026     /* pcmcia memory zone resources */
0027     {
0028         .start      = BCM_PCMCIA_COMMON_BASE_PA,
0029         .end        = BCM_PCMCIA_COMMON_END_PA,
0030         .flags      = IORESOURCE_MEM,
0031     },
0032     {
0033         .start      = BCM_PCMCIA_ATTR_BASE_PA,
0034         .end        = BCM_PCMCIA_ATTR_END_PA,
0035         .flags      = IORESOURCE_MEM,
0036     },
0037     {
0038         .start      = BCM_PCMCIA_IO_BASE_PA,
0039         .end        = BCM_PCMCIA_IO_END_PA,
0040         .flags      = IORESOURCE_MEM,
0041     },
0042 
0043     /* PCMCIA irq */
0044     {
0045         /* start filled at runtime */
0046         .flags      = IORESOURCE_IRQ,
0047     },
0048 
0049     /* declare PCMCIA IO resource also */
0050     {
0051         .start      = BCM_PCMCIA_IO_BASE_PA,
0052         .end        = BCM_PCMCIA_IO_END_PA,
0053         .flags      = IORESOURCE_IO,
0054     },
0055 };
0056 
0057 static struct bcm63xx_pcmcia_platform_data pd;
0058 
0059 static struct platform_device bcm63xx_pcmcia_device = {
0060     .name       = "bcm63xx_pcmcia",
0061     .id     = 0,
0062     .num_resources  = ARRAY_SIZE(pcmcia_resources),
0063     .resource   = pcmcia_resources,
0064     .dev        = {
0065         .platform_data = &pd,
0066     },
0067 };
0068 
0069 static int __init config_pcmcia_cs(unsigned int cs,
0070                    u32 base, unsigned int size)
0071 {
0072     int ret;
0073 
0074     ret = bcm63xx_set_cs_status(cs, 0);
0075     if (!ret)
0076         ret = bcm63xx_set_cs_base(cs, base, size);
0077     if (!ret)
0078         ret = bcm63xx_set_cs_status(cs, 1);
0079     return ret;
0080 }
0081 
0082 static const struct {
0083     unsigned int    cs;
0084     unsigned int    base;
0085     unsigned int    size;
0086 } pcmcia_cs[3] __initconst = {
0087     {
0088         .cs = MPI_CS_PCMCIA_COMMON,
0089         .base   = BCM_PCMCIA_COMMON_BASE_PA,
0090         .size   = BCM_PCMCIA_COMMON_SIZE
0091     },
0092     {
0093         .cs = MPI_CS_PCMCIA_ATTR,
0094         .base   = BCM_PCMCIA_ATTR_BASE_PA,
0095         .size   = BCM_PCMCIA_ATTR_SIZE
0096     },
0097     {
0098         .cs = MPI_CS_PCMCIA_IO,
0099         .base   = BCM_PCMCIA_IO_BASE_PA,
0100         .size   = BCM_PCMCIA_IO_SIZE
0101     },
0102 };
0103 
0104 int __init bcm63xx_pcmcia_register(void)
0105 {
0106     int ret, i;
0107 
0108     if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
0109         return 0;
0110 
0111     /* use correct pcmcia ready gpio depending on processor */
0112     switch (bcm63xx_get_cpu_id()) {
0113     case BCM6348_CPU_ID:
0114         pd.ready_gpio = 22;
0115         break;
0116 
0117     case BCM6358_CPU_ID:
0118         pd.ready_gpio = 18;
0119         break;
0120 
0121     default:
0122         return -ENODEV;
0123     }
0124 
0125     pcmcia_resources[0].start = bcm63xx_regset_address(RSET_PCMCIA);
0126     pcmcia_resources[0].end = pcmcia_resources[0].start +
0127         RSET_PCMCIA_SIZE - 1;
0128     pcmcia_resources[4].start = bcm63xx_get_irq_number(IRQ_PCMCIA);
0129 
0130     /* configure pcmcia chip selects */
0131     for (i = 0; i < 3; i++) {
0132         ret = config_pcmcia_cs(pcmcia_cs[i].cs,
0133                        pcmcia_cs[i].base,
0134                        pcmcia_cs[i].size);
0135         if (ret)
0136             goto out_err;
0137     }
0138 
0139     return platform_device_register(&bcm63xx_pcmcia_device);
0140 
0141 out_err:
0142     pr_err("unable to set pcmcia chip select\n");
0143     return ret;
0144 }