root/arch/mips/alchemy/devboards/platform.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. prom_init
  2. prom_putchar
  3. db1x_power_off
  4. db1x_reset
  5. db1x_late_setup
  6. db1x_register_pcmcia_socket
  7. db1x_register_norflash

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

/* [<][>][^][v][top][bottom][index][help] */