drivers/sh/intc/access.c

Source file repositories/reference/linux-study-clean/drivers/sh/intc/access.c

File Facts

System
Linux kernel
Corpus path
drivers/sh/intc/access.c
Extension
.c
Size
6629 bytes
Lines
247
Domain
Driver Families
Bucket
drivers/sh
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.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/io.h>
#include "internals.h"

unsigned long intc_phys_to_virt(struct intc_desc_int *d, unsigned long address)
{
	struct intc_window *window;
	int k;

	/* scan through physical windows and convert address */
	for (k = 0; k < d->nr_windows; k++) {
		window = d->window + k;

		if (address < window->phys)
			continue;

		if (address >= (window->phys + window->size))
			continue;

		address -= window->phys;
		address += (unsigned long)window->virt;

		return address;
	}

	/* no windows defined, register must be 1:1 mapped virt:phys */
	return address;
}

unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address)
{
	unsigned int k;

	address = intc_phys_to_virt(d, address);

	for (k = 0; k < d->nr_reg; k++) {
		if (d->reg[k] == address)
			return k;
	}

	BUG();
	return 0;
}

unsigned int intc_set_field_from_handle(unsigned int value,
					unsigned int field_value,
					unsigned int handle)
{
	unsigned int width = _INTC_WIDTH(handle);
	unsigned int shift = _INTC_SHIFT(handle);

	value &= ~(((1 << width) - 1) << shift);
	value |= field_value << shift;
	return value;
}

unsigned long intc_get_field_from_handle(unsigned int value, unsigned int handle)
{
	unsigned int width = _INTC_WIDTH(handle);
	unsigned int shift = _INTC_SHIFT(handle);
	unsigned int mask = ((1 << width) - 1) << shift;

	return (value & mask) >> shift;
}

static unsigned long test_8(unsigned long addr, unsigned long h,
			    unsigned long ignore)
{
	void __iomem *ptr = (void __iomem *)addr;
	return intc_get_field_from_handle(__raw_readb(ptr), h);
}

static unsigned long test_16(unsigned long addr, unsigned long h,
			     unsigned long ignore)
{
	void __iomem *ptr = (void __iomem *)addr;
	return intc_get_field_from_handle(__raw_readw(ptr), h);
}

static unsigned long test_32(unsigned long addr, unsigned long h,
			     unsigned long ignore)
{
	void __iomem *ptr = (void __iomem *)addr;
	return intc_get_field_from_handle(__raw_readl(ptr), h);
}

static unsigned long write_8(unsigned long addr, unsigned long h,
			     unsigned long data)
{
	void __iomem *ptr = (void __iomem *)addr;
	__raw_writeb(intc_set_field_from_handle(0, data, h), ptr);

Annotation

Implementation Notes