linux/arch/mips/alchemy/devboards/platform.c
<<
>>
Prefs
   1/*
   2 * devoard misc stuff.
   3 */
   4
   5#include <linux/init.h>
   6#include <linux/mtd/mtd.h>
   7#include <linux/mtd/map.h>
   8#include <linux/mtd/physmap.h>
   9#include <linux/slab.h>
  10#include <linux/platform_device.h>
  11#include <linux/pm.h>
  12
  13#include <asm/bootinfo.h>
  14#include <asm/reboot.h>
  15#include <asm/mach-au1x00/au1000.h>
  16#include <asm/mach-db1x00/bcsr.h>
  17
  18#include <prom.h>
  19
  20void __init prom_init(void)
  21{
  22        unsigned char *memsize_str;
  23        unsigned long memsize;
  24
  25        prom_argc = (int)fw_arg0;
  26        prom_argv = (char **)fw_arg1;
  27        prom_envp = (char **)fw_arg2;
  28
  29        prom_init_cmdline();
  30        memsize_str = prom_getenv("memsize");
  31        if (!memsize_str || kstrtoul(memsize_str, 0, &memsize))
  32                memsize = 64 << 20; /* all devboards have at least 64MB RAM */
  33
  34        add_memory_region(0, memsize, BOOT_MEM_RAM);
  35}
  36
  37void prom_putchar(unsigned char c)
  38{
  39        if (alchemy_get_cputype() == ALCHEMY_CPU_AU1300)
  40                alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
  41        else
  42                alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
  43}
  44
  45
  46static struct platform_device db1x00_rtc_dev = {
  47        .name   = "rtc-au1xxx",
  48        .id     = -1,
  49};
  50
  51
  52static void db1x_power_off(void)
  53{
  54        bcsr_write(BCSR_RESETS, 0);
  55        bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);
  56}
  57
  58static void db1x_reset(char *c)
  59{
  60        bcsr_write(BCSR_RESETS, 0);
  61        bcsr_write(BCSR_SYSTEM, 0);
  62}
  63
  64static int __init db1x_late_setup(void)
  65{
  66        if (!pm_power_off)
  67                pm_power_off = db1x_power_off;
  68        if (!_machine_halt)
  69                _machine_halt = db1x_power_off;
  70        if (!_machine_restart)
  71                _machine_restart = db1x_reset;
  72
  73        platform_device_register(&db1x00_rtc_dev);
  74
  75        return 0;
  76}
  77device_initcall(db1x_late_setup);
  78
  79/* register a pcmcia socket */
  80int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
  81                                       phys_addr_t pcmcia_attr_end,
  82                                       phys_addr_t pcmcia_mem_start,
  83                                       phys_addr_t pcmcia_mem_end,
  84                                       phys_addr_t pcmcia_io_start,
  85                                       phys_addr_t pcmcia_io_end,
  86                                       int card_irq,
  87                                       int cd_irq,
  88                                       int stschg_irq,
  89                                       int eject_irq,
  90                                       int id)
  91{
  92        int cnt, i, ret;
  93        struct resource *sr;
  94        struct platform_device *pd;
  95
  96        cnt = 5;
  97        if (eject_irq)
  98                cnt++;
  99        if (stschg_irq)
 100                cnt++;
 101
 102        sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
 103        if (!sr)
 104                return -ENOMEM;
 105
 106        pd = platform_device_alloc("db1xxx_pcmcia", id);
 107        if (!pd) {
 108                ret = -ENOMEM;
 109                goto out;
 110        }
 111
 112        sr[0].name      = "pcmcia-attr";
 113        sr[0].flags     = IORESOURCE_MEM;
 114        sr[0].start     = pcmcia_attr_start;
 115        sr[0].end       = pcmcia_attr_end;
 116
 117        sr[1].name      = "pcmcia-mem";
 118        sr[1].flags     = IORESOURCE_MEM;
 119        sr[1].start     = pcmcia_mem_start;
 120        sr[1].end       = pcmcia_mem_end;
 121
 122        sr[2].name      = "pcmcia-io";
 123        sr[2].flags     = IORESOURCE_MEM;
 124        sr[2].start     = pcmcia_io_start;
 125        sr[2].end       = pcmcia_io_end;
 126
 127        sr[3].name      = "insert";
 128        sr[3].flags     = IORESOURCE_IRQ;
 129        sr[3].start = sr[3].end = cd_irq;
 130
 131        sr[4].name      = "card";
 132        sr[4].flags     = IORESOURCE_IRQ;
 133        sr[4].start = sr[4].end = card_irq;
 134
 135        i = 5;
 136        if (stschg_irq) {
 137                sr[i].name      = "stschg";
 138                sr[i].flags     = IORESOURCE_IRQ;
 139                sr[i].start = sr[i].end = stschg_irq;
 140                i++;
 141        }
 142        if (eject_irq) {
 143                sr[i].name      = "eject";
 144                sr[i].flags     = IORESOURCE_IRQ;
 145                sr[i].start = sr[i].end = eject_irq;
 146        }
 147
 148        pd->resource = sr;
 149        pd->num_resources = cnt;
 150
 151        ret = platform_device_add(pd);
 152        if (!ret)
 153                return 0;
 154
 155        platform_device_put(pd);
 156out:
 157        kfree(sr);
 158        return ret;
 159}
 160
 161#define YAMON_SIZE      0x00100000
 162#define YAMON_ENV_SIZE  0x00040000
 163
 164int __init db1x_register_norflash(unsigned long size, int width,
 165                                  int swapped)
 166{
 167        struct physmap_flash_data *pfd;
 168        struct platform_device *pd;
 169        struct mtd_partition *parts;
 170        struct resource *res;
 171        int ret, i;
 172
 173        if (size < (8 * 1024 * 1024))
 174                return -EINVAL;
 175
 176        ret = -ENOMEM;
 177        parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL);
 178        if (!parts)
 179                goto out;
 180
 181        res = kzalloc(sizeof(struct resource), GFP_KERNEL);
 182        if (!res)
 183                goto out1;
 184
 185        pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
 186        if (!pfd)
 187                goto out2;
 188
 189        pd = platform_device_alloc("physmap-flash", 0);
 190        if (!pd)
 191                goto out3;
 192
 193        /* NOR flash ends at 0x20000000, regardless of size */
 194        res->start = 0x20000000 - size;
 195        res->end = 0x20000000 - 1;
 196        res->flags = IORESOURCE_MEM;
 197
 198        /* partition setup.  Most Develboards have a switch which allows
 199         * to swap the physical locations of the 2 NOR flash banks.
 200         */
 201        i = 0;
 202        if (!swapped) {
 203                /* first NOR chip */
 204                parts[i].offset = 0;
 205                parts[i].name = "User FS";
 206                parts[i].size = size / 2;
 207                i++;
 208        }
 209
 210        parts[i].offset = MTDPART_OFS_APPEND;
 211        parts[i].name = "User FS 2";
 212        parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
 213        i++;
 214
 215        parts[i].offset = MTDPART_OFS_APPEND;
 216        parts[i].name = "YAMON";
 217        parts[i].size = YAMON_SIZE;
 218        parts[i].mask_flags = MTD_WRITEABLE;
 219        i++;
 220
 221        parts[i].offset = MTDPART_OFS_APPEND;
 222        parts[i].name = "raw kernel";
 223        parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
 224        i++;
 225
 226        parts[i].offset = MTDPART_OFS_APPEND;
 227        parts[i].name = "YAMON Env";
 228        parts[i].size = YAMON_ENV_SIZE;
 229        parts[i].mask_flags = MTD_WRITEABLE;
 230        i++;
 231
 232        if (swapped) {
 233                parts[i].offset = MTDPART_OFS_APPEND;
 234                parts[i].name = "User FS";
 235                parts[i].size = size / 2;
 236                i++;
 237        }
 238
 239        pfd->width = width;
 240        pfd->parts = parts;
 241        pfd->nr_parts = 5;
 242
 243        pd->dev.platform_data = pfd;
 244        pd->resource = res;
 245        pd->num_resources = 1;
 246
 247        ret = platform_device_add(pd);
 248        if (!ret)
 249                return ret;
 250
 251        platform_device_put(pd);
 252out3:
 253        kfree(pfd);
 254out2:
 255        kfree(res);
 256out1:
 257        kfree(parts);
 258out:
 259        return ret;
 260}
 261