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

ssp.c (4743B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  linux/arch/arm/mach-sa1100/ssp.c
      4 *
      5 *  Copyright (C) 2003 Russell King.
      6 *
      7 *  Generic SSP driver.  This provides the generic core for simple
      8 *  IO-based SSP applications.
      9 */
     10#include <linux/module.h>
     11#include <linux/kernel.h>
     12#include <linux/sched.h>
     13#include <linux/errno.h>
     14#include <linux/interrupt.h>
     15#include <linux/ioport.h>
     16#include <linux/init.h>
     17#include <linux/io.h>
     18
     19#include <mach/hardware.h>
     20#include <mach/irqs.h>
     21#include <asm/hardware/ssp.h>
     22
     23#define TIMEOUT 100000
     24
     25static irqreturn_t ssp_interrupt(int irq, void *dev_id)
     26{
     27	unsigned int status = Ser4SSSR;
     28
     29	if (status & SSSR_ROR)
     30		printk(KERN_WARNING "SSP: receiver overrun\n");
     31
     32	Ser4SSSR = SSSR_ROR;
     33
     34	return status ? IRQ_HANDLED : IRQ_NONE;
     35}
     36
     37/**
     38 * ssp_write_word - write a word to the SSP port
     39 * @data: 16-bit, MSB justified data to write.
     40 *
     41 * Wait for a free entry in the SSP transmit FIFO, and write a data
     42 * word to the SSP port.  Wait for the SSP port to start sending
     43 * the data.
     44 *
     45 * The caller is expected to perform the necessary locking.
     46 *
     47 * Returns:
     48 *   %-ETIMEDOUT	timeout occurred
     49 *   0			success
     50 */
     51int ssp_write_word(u16 data)
     52{
     53	int timeout = TIMEOUT;
     54
     55	while (!(Ser4SSSR & SSSR_TNF)) {
     56	        if (!--timeout)
     57	        	return -ETIMEDOUT;
     58		cpu_relax();
     59	}
     60
     61	Ser4SSDR = data;
     62
     63	timeout = TIMEOUT;
     64	while (!(Ser4SSSR & SSSR_BSY)) {
     65	        if (!--timeout)
     66	        	return -ETIMEDOUT;
     67		cpu_relax();
     68	}
     69
     70	return 0;
     71}
     72
     73/**
     74 * ssp_read_word - read a word from the SSP port
     75 *
     76 * Wait for a data word in the SSP receive FIFO, and return the
     77 * received data.  Data is LSB justified.
     78 *
     79 * Note: Currently, if data is not expected to be received, this
     80 * function will wait for ever.
     81 *
     82 * The caller is expected to perform the necessary locking.
     83 *
     84 * Returns:
     85 *   %-ETIMEDOUT	timeout occurred
     86 *   16-bit data	success
     87 */
     88int ssp_read_word(u16 *data)
     89{
     90	int timeout = TIMEOUT;
     91
     92	while (!(Ser4SSSR & SSSR_RNE)) {
     93	        if (!--timeout)
     94	        	return -ETIMEDOUT;
     95		cpu_relax();
     96	}
     97
     98	*data = (u16)Ser4SSDR;
     99
    100	return 0;
    101}
    102
    103/**
    104 * ssp_flush - flush the transmit and receive FIFOs
    105 *
    106 * Wait for the SSP to idle, and ensure that the receive FIFO
    107 * is empty.
    108 *
    109 * The caller is expected to perform the necessary locking.
    110 *
    111 * Returns:
    112 *   %-ETIMEDOUT	timeout occurred
    113 *   0			success
    114 */
    115int ssp_flush(void)
    116{
    117	int timeout = TIMEOUT * 2;
    118
    119	do {
    120		while (Ser4SSSR & SSSR_RNE) {
    121		        if (!--timeout)
    122		        	return -ETIMEDOUT;
    123			(void) Ser4SSDR;
    124		}
    125	        if (!--timeout)
    126	        	return -ETIMEDOUT;
    127	} while (Ser4SSSR & SSSR_BSY);
    128
    129	return 0;
    130}
    131
    132/**
    133 * ssp_enable - enable the SSP port
    134 *
    135 * Turn on the SSP port.
    136 */
    137void ssp_enable(void)
    138{
    139	Ser4SSCR0 |= SSCR0_SSE;
    140}
    141
    142/**
    143 * ssp_disable - shut down the SSP port
    144 *
    145 * Turn off the SSP port, optionally powering it down.
    146 */
    147void ssp_disable(void)
    148{
    149	Ser4SSCR0 &= ~SSCR0_SSE;
    150}
    151
    152/**
    153 * ssp_save_state - save the SSP configuration
    154 * @ssp: pointer to structure to save SSP configuration
    155 *
    156 * Save the configured SSP state for suspend.
    157 */
    158void ssp_save_state(struct ssp_state *ssp)
    159{
    160	ssp->cr0 = Ser4SSCR0;
    161	ssp->cr1 = Ser4SSCR1;
    162
    163	Ser4SSCR0 &= ~SSCR0_SSE;
    164}
    165
    166/**
    167 * ssp_restore_state - restore a previously saved SSP configuration
    168 * @ssp: pointer to configuration saved by ssp_save_state
    169 *
    170 * Restore the SSP configuration saved previously by ssp_save_state.
    171 */
    172void ssp_restore_state(struct ssp_state *ssp)
    173{
    174	Ser4SSSR = SSSR_ROR;
    175
    176	Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE;
    177	Ser4SSCR1 = ssp->cr1;
    178	Ser4SSCR0 = ssp->cr0;
    179}
    180
    181/**
    182 * ssp_init - setup the SSP port
    183 *
    184 * initialise and claim resources for the SSP port.
    185 *
    186 * Returns:
    187 *   %-ENODEV	if the SSP port is unavailable
    188 *   %-EBUSY	if the resources are already in use
    189 *   %0		on success
    190 */
    191int ssp_init(void)
    192{
    193	int ret;
    194
    195	if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE))
    196		return -ENODEV;
    197
    198	if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) {
    199		return -EBUSY;
    200	}
    201
    202	Ser4SSSR = SSSR_ROR;
    203
    204	ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL);
    205	if (ret)
    206		goto out_region;
    207
    208	return 0;
    209
    210 out_region:
    211	release_mem_region(__PREG(Ser4SSCR0), 0x18);
    212	return ret;
    213}
    214
    215/**
    216 * ssp_exit - undo the effects of ssp_init
    217 *
    218 * release and free resources for the SSP port.
    219 */
    220void ssp_exit(void)
    221{
    222	Ser4SSCR0 &= ~SSCR0_SSE;
    223
    224	free_irq(IRQ_Ser4SSP, NULL);
    225	release_mem_region(__PREG(Ser4SSCR0), 0x18);
    226}
    227
    228MODULE_AUTHOR("Russell King");
    229MODULE_DESCRIPTION("SA11x0 SSP PIO driver");
    230MODULE_LICENSE("GPL");
    231
    232EXPORT_SYMBOL(ssp_write_word);
    233EXPORT_SYMBOL(ssp_read_word);
    234EXPORT_SYMBOL(ssp_flush);
    235EXPORT_SYMBOL(ssp_enable);
    236EXPORT_SYMBOL(ssp_disable);
    237EXPORT_SYMBOL(ssp_save_state);
    238EXPORT_SYMBOL(ssp_restore_state);
    239EXPORT_SYMBOL(ssp_init);
    240EXPORT_SYMBOL(ssp_exit);