首先来看s3c_gpio_cfgpin();
int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) { struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);//得到对应GPIO结构体首指针,里面包含了该GPIO的各种参数
unsigned long flags; int offset; int ret; if (!chip) return -EINVAL; offset = pin - chip->chip.base; s3c_gpio_lock(chip, flags); ret = s3c_gpio_do_setcfg(chip, offset, config);//设置该GPIO状态寄存器的数值为config
s3c_gpio_unlock(chip, flags); return ret; }
static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip) { return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL; }
static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip, unsigned int off, unsigned int config) { return (chip->config->set_config)(chip, off, config); }
static struct s3c_gpio_cfg gpio_cfg = { .set_config = s3c_gpio_setcfg_s3c64xx_4bit, .set_pull = s3c_gpio_setpull_updown, .get_pull = s3c_gpio_getpull_updown, };
int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, unsigned int off, unsigned int cfg) { void __iomem *reg = chip->base; unsigned int shift = (off & 7) * 4; u32 con; if (off < 8 && chip->chip.ngpio > 8) reg -= 4; if (s3c_gpio_is_cfg_special(cfg)) { cfg &= 0xf; cfg <<= shift; } con = __raw_readl(reg);//读GPXCON的值 con &= ~(0xf << shift);//清零 con |= cfg;//设置config __raw_writel(con, reg);//写值 return 0; }
其中结构体s3c_gpio_chip如下:
/** * struct s3c_gpio_chip - wrapper for specific implementation of gpio * @chip: The chip structure to be exported via gpiolib. * @base: The base pointer to the gpio configuration registers. * @config: special function and pull-resistor control information. * @lock: Lock for exclusive access to this gpio bank. * @pm_save: Save information for suspend/resume support. * * This wrapper provides the necessary information for the Samsung * specific gpios being registered with gpiolib. * * The lock protects each gpio bank from multiple access of the shared * configuration registers, or from reading of data whilst another thread * is writing to the register set. * * Each chip has its own lock to avoid any contention between different * CPU cores trying to get one lock for different GPIO banks, where each * bank of GPIO has its own register space and configuration registers. */ struct s3c_gpio_chip { struct gpio_chip chip; struct s3c_gpio_cfg *config; struct s3c_gpio_pm *pm; void __iomem *base; int eint_offset; spinlock_t lock; #ifdef CONFIG_PM u32 pm_save[7]; #endif };
static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {//描述了芯片中所有的GPIO端口 { .chip = { .base = S5PV210_GPA0(0), .ngpio = S5PV210_GPIO_A0_NR, .label = "GPA0", .to_irq = s5p_gpiolib_gpioint_to_irq, }, },{ 。。。。 } 。。。。 };
接下来看gpio_set_value();
void __gpio_set_value(unsigned gpio, int value) { struct gpio_chip *chip; chip = gpio_to_chip(gpio);//返回对应于pin的gpio_desc[pin].chip指针
WARN_ON(extra_checks && chip->can_sleep); chip->set(chip, gpio - chip->base, value);//调用chip->set }
那么chip的成员函数set是怎么实现的呢?请看下篇