0001
0002
0003
0004
0005
0006 #include <linux/init.h>
0007 #include <linux/mtd/mtd.h>
0008 #include <linux/mtd/map.h>
0009 #include <linux/mtd/physmap.h>
0010 #include <linux/slab.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/pm.h>
0013
0014 #include <asm/bootinfo.h>
0015 #include <asm/idle.h>
0016 #include <asm/reboot.h>
0017 #include <asm/setup.h>
0018 #include <asm/mach-au1x00/au1000.h>
0019 #include <asm/mach-db1x00/bcsr.h>
0020
0021 #include <prom.h>
0022
0023 void prom_putchar(char c)
0024 {
0025 if (alchemy_get_cputype() == ALCHEMY_CPU_AU1300)
0026 alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
0027 else
0028 alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
0029 }
0030
0031
0032 static struct platform_device db1x00_rtc_dev = {
0033 .name = "rtc-au1xxx",
0034 .id = -1,
0035 };
0036
0037
0038 static void db1x_power_off(void)
0039 {
0040 bcsr_write(BCSR_RESETS, 0);
0041 bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);
0042 while (1)
0043 cpu_wait();
0044 }
0045
0046 static void db1x_reset(char *c)
0047 {
0048 bcsr_write(BCSR_RESETS, 0);
0049 bcsr_write(BCSR_SYSTEM, 0);
0050 }
0051
0052 static int __init db1x_late_setup(void)
0053 {
0054 if (!pm_power_off)
0055 pm_power_off = db1x_power_off;
0056 if (!_machine_halt)
0057 _machine_halt = db1x_power_off;
0058 if (!_machine_restart)
0059 _machine_restart = db1x_reset;
0060
0061 platform_device_register(&db1x00_rtc_dev);
0062
0063 return 0;
0064 }
0065 device_initcall(db1x_late_setup);
0066
0067
0068 int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
0069 phys_addr_t pcmcia_attr_end,
0070 phys_addr_t pcmcia_mem_start,
0071 phys_addr_t pcmcia_mem_end,
0072 phys_addr_t pcmcia_io_start,
0073 phys_addr_t pcmcia_io_end,
0074 int card_irq,
0075 int cd_irq,
0076 int stschg_irq,
0077 int eject_irq,
0078 int id)
0079 {
0080 int cnt, i, ret;
0081 struct resource *sr;
0082 struct platform_device *pd;
0083
0084 cnt = 5;
0085 if (eject_irq)
0086 cnt++;
0087 if (stschg_irq)
0088 cnt++;
0089
0090 sr = kcalloc(cnt, sizeof(struct resource), GFP_KERNEL);
0091 if (!sr)
0092 return -ENOMEM;
0093
0094 pd = platform_device_alloc("db1xxx_pcmcia", id);
0095 if (!pd) {
0096 ret = -ENOMEM;
0097 goto out;
0098 }
0099
0100 sr[0].name = "pcmcia-attr";
0101 sr[0].flags = IORESOURCE_MEM;
0102 sr[0].start = pcmcia_attr_start;
0103 sr[0].end = pcmcia_attr_end;
0104
0105 sr[1].name = "pcmcia-mem";
0106 sr[1].flags = IORESOURCE_MEM;
0107 sr[1].start = pcmcia_mem_start;
0108 sr[1].end = pcmcia_mem_end;
0109
0110 sr[2].name = "pcmcia-io";
0111 sr[2].flags = IORESOURCE_MEM;
0112 sr[2].start = pcmcia_io_start;
0113 sr[2].end = pcmcia_io_end;
0114
0115 sr[3].name = "insert";
0116 sr[3].flags = IORESOURCE_IRQ;
0117 sr[3].start = sr[3].end = cd_irq;
0118
0119 sr[4].name = "card";
0120 sr[4].flags = IORESOURCE_IRQ;
0121 sr[4].start = sr[4].end = card_irq;
0122
0123 i = 5;
0124 if (stschg_irq) {
0125 sr[i].name = "stschg";
0126 sr[i].flags = IORESOURCE_IRQ;
0127 sr[i].start = sr[i].end = stschg_irq;
0128 i++;
0129 }
0130 if (eject_irq) {
0131 sr[i].name = "eject";
0132 sr[i].flags = IORESOURCE_IRQ;
0133 sr[i].start = sr[i].end = eject_irq;
0134 }
0135
0136 pd->resource = sr;
0137 pd->num_resources = cnt;
0138
0139 ret = platform_device_add(pd);
0140 if (!ret)
0141 return 0;
0142
0143 platform_device_put(pd);
0144 out:
0145 kfree(sr);
0146 return ret;
0147 }
0148
0149 #define YAMON_SIZE 0x00100000
0150 #define YAMON_ENV_SIZE 0x00040000
0151
0152 int __init db1x_register_norflash(unsigned long size, int width,
0153 int swapped)
0154 {
0155 struct physmap_flash_data *pfd;
0156 struct platform_device *pd;
0157 struct mtd_partition *parts;
0158 struct resource *res;
0159 int ret, i;
0160
0161 if (size < (8 * 1024 * 1024))
0162 return -EINVAL;
0163
0164 ret = -ENOMEM;
0165 parts = kcalloc(5, sizeof(struct mtd_partition), GFP_KERNEL);
0166 if (!parts)
0167 goto out;
0168
0169 res = kzalloc(sizeof(struct resource), GFP_KERNEL);
0170 if (!res)
0171 goto out1;
0172
0173 pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
0174 if (!pfd)
0175 goto out2;
0176
0177 pd = platform_device_alloc("physmap-flash", 0);
0178 if (!pd)
0179 goto out3;
0180
0181
0182 res->start = 0x20000000 - size;
0183 res->end = 0x20000000 - 1;
0184 res->flags = IORESOURCE_MEM;
0185
0186
0187
0188
0189 i = 0;
0190 if (!swapped) {
0191
0192 parts[i].offset = 0;
0193 parts[i].name = "User FS";
0194 parts[i].size = size / 2;
0195 i++;
0196 }
0197
0198 parts[i].offset = MTDPART_OFS_APPEND;
0199 parts[i].name = "User FS 2";
0200 parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
0201 i++;
0202
0203 parts[i].offset = MTDPART_OFS_APPEND;
0204 parts[i].name = "YAMON";
0205 parts[i].size = YAMON_SIZE;
0206 parts[i].mask_flags = MTD_WRITEABLE;
0207 i++;
0208
0209 parts[i].offset = MTDPART_OFS_APPEND;
0210 parts[i].name = "raw kernel";
0211 parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
0212 i++;
0213
0214 parts[i].offset = MTDPART_OFS_APPEND;
0215 parts[i].name = "YAMON Env";
0216 parts[i].size = YAMON_ENV_SIZE;
0217 parts[i].mask_flags = MTD_WRITEABLE;
0218 i++;
0219
0220 if (swapped) {
0221 parts[i].offset = MTDPART_OFS_APPEND;
0222 parts[i].name = "User FS";
0223 parts[i].size = size / 2;
0224 i++;
0225 }
0226
0227 pfd->width = width;
0228 pfd->parts = parts;
0229 pfd->nr_parts = 5;
0230
0231 pd->dev.platform_data = pfd;
0232 pd->resource = res;
0233 pd->num_resources = 1;
0234
0235 ret = platform_device_add(pd);
0236 if (!ret)
0237 return ret;
0238
0239 platform_device_put(pd);
0240 out3:
0241 kfree(pfd);
0242 out2:
0243 kfree(res);
0244 out1:
0245 kfree(parts);
0246 out:
0247 return ret;
0248 }