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

h3xxx.c (6772B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Support for Compaq iPAQ H3100 and H3600 handheld computers (common code)
      4 *
      5 * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
      6 * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
      7 */
      8
      9#include <linux/kernel.h>
     10#include <linux/gpio/machine.h>
     11#include <linux/gpio.h>
     12#include <linux/gpio_keys.h>
     13#include <linux/input.h>
     14#include <linux/mtd/mtd.h>
     15#include <linux/mtd/partitions.h>
     16#include <linux/platform_data/gpio-htc-egpio.h>
     17#include <linux/platform_data/sa11x0-serial.h>
     18#include <linux/platform_device.h>
     19#include <linux/serial_core.h>
     20
     21#include <asm/mach/flash.h>
     22#include <asm/mach/map.h>
     23
     24#include <mach/h3xxx.h>
     25#include <mach/irqs.h>
     26
     27#include "generic.h"
     28
     29/*
     30 * H3xxx flash support
     31 */
     32static struct mtd_partition h3xxx_partitions[] = {
     33	{
     34		.name		= "H3XXX boot firmware",
     35		.size		= 0x00040000,
     36		.offset		= 0,
     37		.mask_flags	= MTD_WRITEABLE,  /* force read-only */
     38	}, {
     39		.name		= "H3XXX rootfs",
     40		.size		= MTDPART_SIZ_FULL,
     41		.offset		= 0x00040000,
     42	}
     43};
     44
     45static void h3xxx_set_vpp(int vpp)
     46{
     47	gpio_set_value(H3XXX_EGPIO_VPP_ON, vpp);
     48}
     49
     50static int h3xxx_flash_init(void)
     51{
     52	int err = gpio_request(H3XXX_EGPIO_VPP_ON, "Flash Vpp");
     53	if (err) {
     54		pr_err("%s: can't request H3XXX_EGPIO_VPP_ON\n", __func__);
     55		return err;
     56	}
     57
     58	err = gpio_direction_output(H3XXX_EGPIO_VPP_ON, 0);
     59	if (err)
     60		gpio_free(H3XXX_EGPIO_VPP_ON);
     61
     62	return err;
     63}
     64
     65static void h3xxx_flash_exit(void)
     66{
     67	gpio_free(H3XXX_EGPIO_VPP_ON);
     68}
     69
     70static struct flash_platform_data h3xxx_flash_data = {
     71	.map_name	= "cfi_probe",
     72	.set_vpp	= h3xxx_set_vpp,
     73	.init		= h3xxx_flash_init,
     74	.exit		= h3xxx_flash_exit,
     75	.parts		= h3xxx_partitions,
     76	.nr_parts	= ARRAY_SIZE(h3xxx_partitions),
     77};
     78
     79static struct resource h3xxx_flash_resource =
     80	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
     81
     82
     83/*
     84 * H3xxx uart support
     85 */
     86static void h3xxx_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
     87{
     88	if (port->mapbase == _Ser3UTCR0) {
     89		if (!gpio_request(H3XXX_EGPIO_RS232_ON, "RS232 transceiver")) {
     90			gpio_direction_output(H3XXX_EGPIO_RS232_ON, !state);
     91			gpio_free(H3XXX_EGPIO_RS232_ON);
     92		} else {
     93			pr_err("%s: can't request H3XXX_EGPIO_RS232_ON\n",
     94				__func__);
     95		}
     96	}
     97}
     98
     99/*
    100 * Enable/Disable wake up events for this serial port.
    101 * Obviously, we only support this on the normal COM port.
    102 */
    103static int h3xxx_uart_set_wake(struct uart_port *port, u_int enable)
    104{
    105	int err = -EINVAL;
    106
    107	if (port->mapbase == _Ser3UTCR0) {
    108		if (enable)
    109			PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */
    110		else
    111			PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
    112		err = 0;
    113	}
    114	return err;
    115}
    116
    117static struct sa1100_port_fns h3xxx_port_fns __initdata = {
    118	.pm		= h3xxx_uart_pm,
    119	.set_wake	= h3xxx_uart_set_wake,
    120};
    121
    122static struct gpiod_lookup_table h3xxx_uart3_gpio_table = {
    123	.dev_id = "sa11x0-uart.3",
    124	.table = {
    125		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_DCD, "dcd", GPIO_ACTIVE_LOW),
    126		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_CTS, "cts", GPIO_ACTIVE_LOW),
    127		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_RTS, "rts", GPIO_ACTIVE_LOW),
    128		{ },
    129	},
    130};
    131
    132/*
    133 * EGPIO
    134 */
    135
    136static struct resource egpio_resources[] = {
    137	[0] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4),
    138};
    139
    140static struct htc_egpio_chip egpio_chips[] = {
    141	[0] = {
    142		.reg_start	= 0,
    143		.gpio_base	= H3XXX_EGPIO_BASE,
    144		.num_gpios	= 16,
    145		.direction	= HTC_EGPIO_OUTPUT,
    146		.initial_values	= 0x0080, /* H3XXX_EGPIO_RS232_ON */
    147	},
    148};
    149
    150static struct htc_egpio_platform_data egpio_info = {
    151	.reg_width	= 16,
    152	.bus_width	= 16,
    153	.chip		= egpio_chips,
    154	.num_chips	= ARRAY_SIZE(egpio_chips),
    155};
    156
    157static struct platform_device h3xxx_egpio = {
    158	.name		= "htc-egpio",
    159	.id		= -1,
    160	.resource	= egpio_resources,
    161	.num_resources	= ARRAY_SIZE(egpio_resources),
    162	.dev		= {
    163		.platform_data = &egpio_info,
    164	},
    165};
    166
    167/*
    168 * GPIO keys
    169 */
    170
    171static struct gpio_keys_button h3xxx_button_table[] = {
    172	{
    173		.code		= KEY_POWER,
    174		.gpio		= H3XXX_GPIO_PWR_BUTTON,
    175		.desc		= "Power Button",
    176		.active_low	= 1,
    177		.type		= EV_KEY,
    178		.wakeup		= 1,
    179	}, {
    180		.code		= KEY_ENTER,
    181		.gpio		= H3XXX_GPIO_ACTION_BUTTON,
    182		.active_low	= 1,
    183		.desc		= "Action button",
    184		.type		= EV_KEY,
    185		.wakeup		= 0,
    186	},
    187};
    188
    189static struct gpio_keys_platform_data h3xxx_keys_data = {
    190	.buttons  = h3xxx_button_table,
    191	.nbuttons = ARRAY_SIZE(h3xxx_button_table),
    192};
    193
    194static struct platform_device h3xxx_keys = {
    195	.name	= "gpio-keys",
    196	.id	= -1,
    197	.dev	= {
    198		.platform_data = &h3xxx_keys_data,
    199	},
    200};
    201
    202static struct resource h3xxx_micro_resources[] = {
    203	DEFINE_RES_MEM(0x80010000, SZ_4K),
    204	DEFINE_RES_MEM(0x80020000, SZ_4K),
    205	DEFINE_RES_IRQ(IRQ_Ser1UART),
    206};
    207
    208struct platform_device h3xxx_micro_asic = {
    209	.name = "ipaq-h3xxx-micro",
    210	.id = -1,
    211	.resource = h3xxx_micro_resources,
    212	.num_resources = ARRAY_SIZE(h3xxx_micro_resources),
    213};
    214
    215static struct platform_device *h3xxx_devices[] = {
    216	&h3xxx_egpio,
    217	&h3xxx_keys,
    218	&h3xxx_micro_asic,
    219};
    220
    221static struct gpiod_lookup_table h3xxx_pcmcia_gpio_table = {
    222	.dev_id = "sa11x0-pcmcia",
    223	.table = {
    224		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_CD0,
    225			    "pcmcia0-detect", GPIO_ACTIVE_LOW),
    226		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_IRQ0,
    227			    "pcmcia0-ready", GPIO_ACTIVE_HIGH),
    228		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_CD1,
    229			    "pcmcia1-detect", GPIO_ACTIVE_LOW),
    230		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_IRQ1,
    231			    "pcmcia1-ready", GPIO_ACTIVE_HIGH),
    232		{ },
    233	},
    234};
    235
    236void __init h3xxx_mach_init(void)
    237{
    238	gpiod_add_lookup_table(&h3xxx_pcmcia_gpio_table);
    239	gpiod_add_lookup_table(&h3xxx_uart3_gpio_table);
    240	sa1100_register_uart_fns(&h3xxx_port_fns);
    241	sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
    242	platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
    243}
    244
    245static struct map_desc h3600_io_desc[] __initdata = {
    246	{	/* static memory bank 2  CS#2 */
    247		.virtual	=  H3600_BANK_2_VIRT,
    248		.pfn		= __phys_to_pfn(SA1100_CS2_PHYS),
    249		.length		= 0x02800000,
    250		.type		= MT_DEVICE
    251	}, {	/* static memory bank 4  CS#4 */
    252		.virtual	=  H3600_BANK_4_VIRT,
    253		.pfn		= __phys_to_pfn(SA1100_CS4_PHYS),
    254		.length		= 0x00800000,
    255		.type		= MT_DEVICE
    256	}, {	/* EGPIO 0		CS#5 */
    257		.virtual	=  H3600_EGPIO_VIRT,
    258		.pfn		= __phys_to_pfn(H3600_EGPIO_PHYS),
    259		.length		= 0x01000000,
    260		.type		= MT_DEVICE
    261	}
    262};
    263
    264/*
    265 * Common map_io initialization
    266 */
    267
    268void __init h3xxx_map_io(void)
    269{
    270	sa1100_map_io();
    271	iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc));
    272
    273	sa1100_register_uart(0, 3); /* Common serial port */
    274//	sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
    275
    276	/* Ensure those pins are outputs and driving low  */
    277	PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
    278	PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
    279
    280	/* Configure suspend conditions */
    281	PGSR = 0;
    282	PCFR = PCFR_OPDE;
    283	PSDR = 0;
    284
    285	GPCR = 0x0fffffff;	/* All outputs are set low by default */
    286	GPDR = 0;		/* Configure all GPIOs as input */
    287}
    288