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/reboot.h>
  14#include <asm/mach-db1x00/bcsr.h>
  15
  16static void db1x_power_off(void)
  17{
  18        bcsr_write(BCSR_RESETS, 0);
  19        bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);
  20}
  21
  22static void db1x_reset(char *c)
  23{
  24        bcsr_write(BCSR_RESETS, 0);
  25        bcsr_write(BCSR_SYSTEM, 0);
  26}
  27
  28static int __init db1x_poweroff_setup(void)
  29{
  30        if (!pm_power_off)
  31                pm_power_off = db1x_power_off;
  32        if (!_machine_halt)
  33                _machine_halt = db1x_power_off;
  34        if (!_machine_restart)
  35                _machine_restart = db1x_reset;
  36
  37        return 0;
  38}
  39late_initcall(db1x_poweroff_setup);
  40
  41/* register a pcmcia socket */
  42int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
  43                                       phys_addr_t pcmcia_attr_end,
  44                                       phys_addr_t pcmcia_mem_start,
  45                                       phys_addr_t pcmcia_mem_end,
  46                                       phys_addr_t pcmcia_io_start,
  47                                       phys_addr_t pcmcia_io_end,
  48                                       int card_irq,
  49                                       int cd_irq,
  50                                       int stschg_irq,
  51                                       int eject_irq,
  52                                       int id)
  53{
  54        int cnt, i, ret;
  55        struct resource *sr;
  56        struct platform_device *pd;
  57
  58        cnt = 5;
  59        if (eject_irq)
  60                cnt++;
  61        if (stschg_irq)
  62                cnt++;
  63
  64        sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
  65        if (!sr)
  66                return -ENOMEM;
  67
  68        pd = platform_device_alloc("db1xxx_pcmcia", id);
  69        if (!pd) {
  70                ret = -ENOMEM;
  71                goto out;
  72        }
  73
  74        sr[0].name      = "pcmcia-attr";
  75        sr[0].flags     = IORESOURCE_MEM;
  76        sr[0].start     = pcmcia_attr_start;
  77        sr[0].end       = pcmcia_attr_end;
  78
  79        sr[1].name      = "pcmcia-mem";
  80        sr[1].flags     = IORESOURCE_MEM;
  81        sr[1].start     = pcmcia_mem_start;
  82        sr[1].end       = pcmcia_mem_end;
  83
  84        sr[2].name      = "pcmcia-io";
  85        sr[2].flags     = IORESOURCE_MEM;
  86        sr[2].start     = pcmcia_io_start;
  87        sr[2].end       = pcmcia_io_end;
  88
  89        sr[3].name      = "insert";
  90        sr[3].flags     = IORESOURCE_IRQ;
  91        sr[3].start = sr[3].end = cd_irq;
  92
  93        sr[4].name      = "card";
  94        sr[4].flags     = IORESOURCE_IRQ;
  95        sr[4].start = sr[4].end = card_irq;
  96
  97        i = 5;
  98        if (stschg_irq) {
  99                sr[i].name      = "stschg";
 100                sr[i].flags     = IORESOURCE_IRQ;
 101                sr[i].start = sr[i].end = stschg_irq;
 102                i++;
 103        }
 104        if (eject_irq) {
 105                sr[i].name      = "eject";
 106                sr[i].flags     = IORESOURCE_IRQ;
 107                sr[i].start = sr[i].end = eject_irq;
 108        }
 109
 110        pd->resource = sr;
 111        pd->num_resources = cnt;
 112
 113        ret = platform_device_add(pd);
 114        if (!ret)
 115                return 0;
 116
 117        platform_device_put(pd);
 118out:
 119        kfree(sr);
 120        return ret;
 121}
 122
 123#define YAMON_SIZE      0x00100000
 124#define YAMON_ENV_SIZE  0x00040000
 125
 126int __init db1x_register_norflash(unsigned long size, int width,
 127                                  int swapped)
 128{
 129        struct physmap_flash_data *pfd;
 130        struct platform_device *pd;
 131        struct mtd_partition *parts;
 132        struct resource *res;
 133        int ret, i;
 134
 135        if (size < (8 * 1024 * 1024))
 136                return -EINVAL;
 137
 138        ret = -ENOMEM;
 139        parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL);
 140        if (!parts)
 141                goto out;
 142
 143        res = kzalloc(sizeof(struct resource), GFP_KERNEL);
 144        if (!res)
 145                goto out1;
 146
 147        pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
 148        if (!pfd)
 149                goto out2;
 150
 151        pd = platform_device_alloc("physmap-flash", 0);
 152        if (!pd)
 153                goto out3;
 154
 155        /* NOR flash ends at 0x20000000, regardless of size */
 156        res->start = 0x20000000 - size;
 157        res->end = 0x20000000 - 1;
 158        res->flags = IORESOURCE_MEM;
 159
 160        /* partition setup.  Most Develboards have a switch which allows
 161         * to swap the physical locations of the 2 NOR flash banks.
 162         */
 163        i = 0;
 164        if (!swapped) {
 165                /* first NOR chip */
 166                parts[i].offset = 0;
 167                parts[i].name = "User FS";
 168                parts[i].size = size / 2;
 169                i++;
 170        }
 171
 172        parts[i].offset = MTDPART_OFS_APPEND;
 173        parts[i].name = "User FS 2";
 174        parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
 175        i++;
 176
 177        parts[i].offset = MTDPART_OFS_APPEND;
 178        parts[i].name = "YAMON";
 179        parts[i].size = YAMON_SIZE;
 180        parts[i].mask_flags = MTD_WRITEABLE;
 181        i++;
 182
 183        parts[i].offset = MTDPART_OFS_APPEND;
 184        parts[i].name = "raw kernel";
 185        parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
 186        i++;
 187
 188        parts[i].offset = MTDPART_OFS_APPEND;
 189        parts[i].name = "YAMON Env";
 190        parts[i].size = YAMON_ENV_SIZE;
 191        parts[i].mask_flags = MTD_WRITEABLE;
 192        i++;
 193
 194        if (swapped) {
 195                parts[i].offset = MTDPART_OFS_APPEND;
 196                parts[i].name = "User FS";
 197                parts[i].size = size / 2;
 198                i++;
 199        }
 200
 201        pfd->width = width;
 202        pfd->parts = parts;
 203        pfd->nr_parts = 5;
 204
 205        pd->dev.platform_data = pfd;
 206        pd->resource = res;
 207        pd->num_resources = 1;
 208
 209        ret = platform_device_add(pd);
 210        if (!ret)
 211                return ret;
 212
 213        platform_device_put(pd);
 214out3:
 215        kfree(pfd);
 216out2:
 217        kfree(res);
 218out1:
 219        kfree(parts);
 220out:
 221        return ret;
 222}
 223
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.