drivers/spi/spi-mpc52xx-psc.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-mpc52xx-psc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-mpc52xx-psc.c- Extension
.c- Size
- 9708 bytes
- Lines
- 367
- Domain
- Driver Families
- Bucket
- drivers/spi
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/types.hlinux/errno.hlinux/interrupt.hlinux/platform_device.hlinux/property.hlinux/workqueue.hlinux/completion.hlinux/io.hlinux/delay.hlinux/spi/spi.hlinux/slab.hasm/mpc52xx.hasm/mpc52xx_psc.h
Detected Declarations
struct mpc52xx_psc_spistruct mpc52xx_psc_spi_csfunction mpc52xx_psc_spi_transfer_setupfunction mpc52xx_psc_spi_activate_csfunction mpc52xx_psc_spi_transfer_rxtxfunction mpc52xx_psc_spi_transfer_one_messagefunction mpc52xx_psc_spi_setupfunction mpc52xx_psc_spi_cleanupfunction mpc52xx_psc_spi_port_configfunction mpc52xx_psc_spi_isrfunction mpc52xx_psc_spi_of_probe
Annotated Snippet
struct mpc52xx_psc_spi {
/* driver internal data */
struct mpc52xx_psc __iomem *psc;
struct mpc52xx_psc_fifo __iomem *fifo;
int irq;
u8 bits_per_word;
struct completion done;
};
/* controller state */
struct mpc52xx_psc_spi_cs {
int bits_per_word;
int speed_hz;
};
/* set clock freq, clock ramp, bits per work
* if t is NULL then reset the values to the default values
*/
static int mpc52xx_psc_spi_transfer_setup(struct spi_device *spi,
struct spi_transfer *t)
{
struct mpc52xx_psc_spi_cs *cs = spi->controller_state;
cs->speed_hz = (t && t->speed_hz)
? t->speed_hz : spi->max_speed_hz;
cs->bits_per_word = (t && t->bits_per_word)
? t->bits_per_word : spi->bits_per_word;
cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8;
return 0;
}
static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi)
{
struct mpc52xx_psc_spi_cs *cs = spi->controller_state;
struct mpc52xx_psc_spi *mps = spi_controller_get_devdata(spi->controller);
struct mpc52xx_psc __iomem *psc = mps->psc;
u32 sicr;
u16 ccr;
sicr = in_be32(&psc->sicr);
/* Set clock phase and polarity */
if (spi->mode & SPI_CPHA)
sicr |= 0x00001000;
else
sicr &= ~0x00001000;
if (spi->mode & SPI_CPOL)
sicr |= 0x00002000;
else
sicr &= ~0x00002000;
if (spi->mode & SPI_LSB_FIRST)
sicr |= 0x10000000;
else
sicr &= ~0x10000000;
out_be32(&psc->sicr, sicr);
/* Set clock frequency and bits per word
* Because psc->ccr is defined as 16bit register instead of 32bit
* just set the lower byte of BitClkDiv
*/
ccr = in_be16((u16 __iomem *)&psc->ccr);
ccr &= 0xFF00;
if (cs->speed_hz)
ccr |= (MCLK / cs->speed_hz - 1) & 0xFF;
else /* by default SPI Clk 1MHz */
ccr |= (MCLK / 1000000 - 1) & 0xFF;
out_be16((u16 __iomem *)&psc->ccr, ccr);
mps->bits_per_word = cs->bits_per_word;
}
#define MPC52xx_PSC_BUFSIZE (MPC52xx_PSC_RFNUM_MASK + 1)
/* wake up when 80% fifo full */
#define MPC52xx_PSC_RFALARM (MPC52xx_PSC_BUFSIZE * 20 / 100)
static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
struct spi_transfer *t)
{
struct mpc52xx_psc_spi *mps = spi_controller_get_devdata(spi->controller);
struct mpc52xx_psc __iomem *psc = mps->psc;
struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
unsigned rb = 0; /* number of bytes received */
unsigned sb = 0; /* number of bytes sent */
unsigned char *rx_buf = (unsigned char *)t->rx_buf;
unsigned char *tx_buf = (unsigned char *)t->tx_buf;
unsigned rfalarm;
unsigned send_at_once = MPC52xx_PSC_BUFSIZE;
unsigned recv_at_once;
int last_block = 0;
Annotation
- Immediate include surface: `linux/module.h`, `linux/types.h`, `linux/errno.h`, `linux/interrupt.h`, `linux/platform_device.h`, `linux/property.h`, `linux/workqueue.h`, `linux/completion.h`.
- Detected declarations: `struct mpc52xx_psc_spi`, `struct mpc52xx_psc_spi_cs`, `function mpc52xx_psc_spi_transfer_setup`, `function mpc52xx_psc_spi_activate_cs`, `function mpc52xx_psc_spi_transfer_rxtx`, `function mpc52xx_psc_spi_transfer_one_message`, `function mpc52xx_psc_spi_setup`, `function mpc52xx_psc_spi_cleanup`, `function mpc52xx_psc_spi_port_config`, `function mpc52xx_psc_spi_isr`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.