Path: blob/master/arch/mips/alchemy/devboards/platform.c
26481 views
// SPDX-License-Identifier: GPL-2.01/*2* devoard misc stuff.3*/45#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>1213#include <asm/bootinfo.h>14#include <asm/idle.h>15#include <asm/reboot.h>16#include <asm/setup.h>17#include <asm/mach-au1x00/au1000.h>18#include <asm/mach-db1x00/bcsr.h>1920#include <prom.h>2122void prom_putchar(char c)23{24if (alchemy_get_cputype() == ALCHEMY_CPU_AU1300)25alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);26else27alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);28}293031static struct platform_device db1x00_rtc_dev = {32.name = "rtc-au1xxx",33.id = -1,34};353637static void db1x_power_off(void)38{39bcsr_write(BCSR_RESETS, 0);40bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);41while (1) /* sit and spin */42cpu_wait();43}4445static void db1x_reset(char *c)46{47bcsr_write(BCSR_RESETS, 0);48bcsr_write(BCSR_SYSTEM, 0);49}5051static int __init db1x_late_setup(void)52{53if (!pm_power_off)54pm_power_off = db1x_power_off;55if (!_machine_halt)56_machine_halt = db1x_power_off;57if (!_machine_restart)58_machine_restart = db1x_reset;5960platform_device_register(&db1x00_rtc_dev);6162return 0;63}64device_initcall(db1x_late_setup);6566/* register a pcmcia socket */67int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,68phys_addr_t pcmcia_attr_end,69phys_addr_t pcmcia_mem_start,70phys_addr_t pcmcia_mem_end,71phys_addr_t pcmcia_io_start,72phys_addr_t pcmcia_io_end,73int card_irq,74int cd_irq,75int stschg_irq,76int eject_irq,77int id)78{79int cnt, i, ret;80struct resource *sr;81struct platform_device *pd;8283cnt = 5;84if (eject_irq)85cnt++;86if (stschg_irq)87cnt++;8889sr = kcalloc(cnt, sizeof(struct resource), GFP_KERNEL);90if (!sr)91return -ENOMEM;9293pd = platform_device_alloc("db1xxx_pcmcia", id);94if (!pd) {95ret = -ENOMEM;96goto out;97}9899sr[0].name = "pcmcia-attr";100sr[0].flags = IORESOURCE_MEM;101sr[0].start = pcmcia_attr_start;102sr[0].end = pcmcia_attr_end;103104sr[1].name = "pcmcia-mem";105sr[1].flags = IORESOURCE_MEM;106sr[1].start = pcmcia_mem_start;107sr[1].end = pcmcia_mem_end;108109sr[2].name = "pcmcia-io";110sr[2].flags = IORESOURCE_MEM;111sr[2].start = pcmcia_io_start;112sr[2].end = pcmcia_io_end;113114sr[3].name = "insert";115sr[3].flags = IORESOURCE_IRQ;116sr[3].start = sr[3].end = cd_irq;117118sr[4].name = "card";119sr[4].flags = IORESOURCE_IRQ;120sr[4].start = sr[4].end = card_irq;121122i = 5;123if (stschg_irq) {124sr[i].name = "stschg";125sr[i].flags = IORESOURCE_IRQ;126sr[i].start = sr[i].end = stschg_irq;127i++;128}129if (eject_irq) {130sr[i].name = "eject";131sr[i].flags = IORESOURCE_IRQ;132sr[i].start = sr[i].end = eject_irq;133}134135pd->resource = sr;136pd->num_resources = cnt;137138ret = platform_device_add(pd);139if (!ret)140return 0;141142platform_device_put(pd);143out:144kfree(sr);145return ret;146}147148#define YAMON_SIZE 0x00100000149#define YAMON_ENV_SIZE 0x00040000150151int __init db1x_register_norflash(unsigned long size, int width,152int swapped)153{154struct physmap_flash_data *pfd;155struct platform_device *pd;156struct mtd_partition *parts;157struct resource *res;158int ret, i;159160if (size < (8 * 1024 * 1024))161return -EINVAL;162163ret = -ENOMEM;164parts = kcalloc(5, sizeof(struct mtd_partition), GFP_KERNEL);165if (!parts)166goto out;167168res = kzalloc(sizeof(struct resource), GFP_KERNEL);169if (!res)170goto out1;171172pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);173if (!pfd)174goto out2;175176pd = platform_device_alloc("physmap-flash", 0);177if (!pd)178goto out3;179180/* NOR flash ends at 0x20000000, regardless of size */181res->start = 0x20000000 - size;182res->end = 0x20000000 - 1;183res->flags = IORESOURCE_MEM;184185/* partition setup. Most Develboards have a switch which allows186* to swap the physical locations of the 2 NOR flash banks.187*/188i = 0;189if (!swapped) {190/* first NOR chip */191parts[i].offset = 0;192parts[i].name = "User FS";193parts[i].size = size / 2;194i++;195}196197parts[i].offset = MTDPART_OFS_APPEND;198parts[i].name = "User FS 2";199parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);200i++;201202parts[i].offset = MTDPART_OFS_APPEND;203parts[i].name = "YAMON";204parts[i].size = YAMON_SIZE;205parts[i].mask_flags = MTD_WRITEABLE;206i++;207208parts[i].offset = MTDPART_OFS_APPEND;209parts[i].name = "raw kernel";210parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;211i++;212213parts[i].offset = MTDPART_OFS_APPEND;214parts[i].name = "YAMON Env";215parts[i].size = YAMON_ENV_SIZE;216parts[i].mask_flags = MTD_WRITEABLE;217i++;218219if (swapped) {220parts[i].offset = MTDPART_OFS_APPEND;221parts[i].name = "User FS";222parts[i].size = size / 2;223i++;224}225226pfd->width = width;227pfd->parts = parts;228pfd->nr_parts = 5;229230pd->dev.platform_data = pfd;231pd->resource = res;232pd->num_resources = 1;233234ret = platform_device_add(pd);235if (!ret)236return ret;237238platform_device_put(pd);239out3:240kfree(pfd);241out2:242kfree(res);243out1:244kfree(parts);245out:246return ret;247}248249250