cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

platform.c (5064B)


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