read-write register interface provided by the Kernel for portability
Arm is an IO and memory unified address, other platforms such as x86 is IO and memory independent address access mode, using the kernel provided register read-write interface Writel\readl has portability
In the article essay –linux character device Driver Development Foundation written in front of the driver in the static map operation register, all use # define Rgpj0con * ((volatile unsigned int *) Gpj0con) to access the Register, Such a practice is not very good in the driver because it is not portable in the case of different platforms. Now write the drive is written on the arm platform, ARM belongs to the memory and IO Unified address, in the read and write registers for the IO operation, IO operation is the same as read and write memory (Io also has an address), this is called unified addressing. But there are other CPUs (like x86) that are non-uniform, and that the CPU's approach to IO operations is different from the way memory is read and written. Then there is a problem in this case, if the write driver requires not only to be able to run under arm, but also to be able to run under X86 if it is also a # define Rgpj0con * ((volatile unsigned int *) Gpj0con) The way it is obviously inappropriate and requires a larger revision. What can we do to enable him to have a strong transplant? --The kernel has helped us figure out that the kernel provides access registers to read and write interfaces (functions) that use these functions to be portable. The implementation of the principle is to use conditional compilation, the following comparison:
code example (static mapping):
...
#include <mach/regs-gpio.h> //Virtual address mapping table
#include <mach/gpio-bank.h>
#include <linux/io.h >
#include <linux/ioport.h>
#define GPJ0CON s5pv210_gpj0con
#define GPJ0DAT s5pv210_ Gpj0dat ...
...
Writel (0x11111111, Gpj0con);
Writel ((0<<3) | (0<<4) | (0<<5)), gpj0dat);
...
code example (Dynamic mapping):
#include <linux/io.h> #include <linux/ioport.h> ... #define GPJ0CON_PA 0xe0200240//Physical address of register to operate #define S5P_GPJ0REG (x) (x) #define S5p_gpj0con s5p_gpj0reg (0) #define S5p_gpj0dat S5p_gpj0reg (4) static void __iomem *baseaddr; The base address of the virtual address of the register, used to hold the return value of the ioremap ... if (!request_mem_region (GPJ0CON_PA, 8, "gpj0base"))//memory resource request RET
Urn-einval;
BASEADDR = Ioremap (GPJ0CON_PA, 8);
Writel (0x11111111, baseaddr + S5p_gpj0con); Writel ((0<<3) | (0<<4) |
(0<<5)), baseaddr + S5p_gpj0dat); ...