spin_lock的一个例子:GPIO寄存器控制

mx27的GPIO控制时, 比如设置输入输出方向函数:

/*!
 * Exported function to set a GPIO pin's direction
 * @param pin           a name defined by \b iomux_pin_name_t
 * @param is_input      1 (or non-zero) for input; 0 for output
 */
void mxc_set_gpio_direction(iomux_pin_name_t pin, int is_input)
{
        struct gpio_port *port;
        u32 gpio = IOMUX_TO_GPIO(pin);

        if (check_gpio(gpio) < 0)
                return;
        port = get_gpio_port(gpio);
        spin_lock(&port->lock);
        _set_gpio_direction(port, GPIO_TO_INDEX(gpio), is_input);
        spin_unlock(&port->lock);
}
/*
 * Set a GPIO pin's direction
 * @param port          pointer to a gpio_port
 * @param index         gpio pin index value (0~31)
 * @param is_input      0 for output; non-zero for input
 */
static void _set_gpio_direction(struct gpio_port *port, u32 index, int is_input)
{
        u32 reg = port->base + GPIO_GDIR;
        u32 l;

        l = __raw_readl(reg);
        if (is_input)
                l &= ~(1 << index);
        else
                l |= 1 << index;
        __raw_writel(l, reg);
}
这里就用到了一个自旋锁,因为mx27系统的gpio控制寄存器,都是好多个pin共享的, 所以操作时,尤其是写时,需要避免竞争,要加个自旋锁。
除了方向控制寄存器,还有写数据寄存器:

/*!
 * Exported function to set a GPIO pin's data output
 * @param pin           a name defined by \b iomux_pin_name_t
 * @param data          value to be set (only 0 or 1 is valid)
 */
void mxc_set_gpio_dataout(iomux_pin_name_t pin, u32 data)
{
        struct gpio_port *port;
        u32 gpio = IOMUX_TO_GPIO(pin);

        if (check_gpio(gpio) < 0)
                return;

        port = get_gpio_port(gpio);
        spin_lock(&port->lock);
        _set_gpio_dataout(port, GPIO_TO_INDEX(gpio), (data == 0) ? 0 : 1);
        spin_unlock(&port->lock);
}
/*
 * Set a GPIO pin's data output
 * @param port          pointer to a gpio_port
 * @param index         gpio pin index value (0~31)
 * @param data          value to be set (only 0 or 1 is valid)
 */
static void _set_gpio_dataout(struct gpio_port *port, u32 index, u32 data)
{
        u32 reg = port->base + GPIO_DR;
        u32 l = 0;

        l = (__raw_readl(reg) & (~(1 << index))) | (data << index);
        __raw_writel(l, reg);
}
还有request gpio:

static inline int _request_gpio(struct gpio_port *port, u32 index)
{
        spin_lock(&port->lock);
        if (port->reserved_map & (1 << index)) {
                printk(KERN_ERR
                       "GPIO port %d (0-based), pin %d is already reserved!\n",
                       port->num, index);
                dump_stack();
                spin_unlock(&port->lock);
                return -1;
        }
        port->reserved_map |= (1 << index);
        spin_unlock(&port->lock);
        return 0;
}

/*!
 * Request ownership for a GPIO pin. The caller has to check the return value
 * of this function to make sure it returns 0 before make use of that pin.
 * @param pin           a name defined by \b iomux_pin_name_t
 * @return              0 if successful; Non-zero otherwise
 */
int mxc_request_gpio(iomux_pin_name_t pin)
{
        struct gpio_port *port;
        u32 index, gpio = IOMUX_TO_GPIO(pin);

        if (check_gpio(gpio) < 0)
                return -EINVAL;

        port = get_gpio_port(gpio);
        index = GPIO_TO_INDEX(gpio);

        return _request_gpio(port, index);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值