Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/kernel/gpio_txx9.c
26442 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* A gpio chip driver for TXx9 SoCs
4
*
5
* Copyright (C) 2008 Atsushi Nemoto <[email protected]>
6
*/
7
8
#include <linux/init.h>
9
#include <linux/spinlock.h>
10
#include <linux/gpio/driver.h>
11
#include <linux/errno.h>
12
#include <linux/io.h>
13
#include <asm/txx9pio.h>
14
15
static DEFINE_SPINLOCK(txx9_gpio_lock);
16
17
static struct txx9_pio_reg __iomem *txx9_pioptr;
18
19
static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
20
{
21
return !!(__raw_readl(&txx9_pioptr->din) & (1 << offset));
22
}
23
24
static void txx9_gpio_set_raw(unsigned int offset, int value)
25
{
26
u32 val;
27
val = __raw_readl(&txx9_pioptr->dout);
28
if (value)
29
val |= 1 << offset;
30
else
31
val &= ~(1 << offset);
32
__raw_writel(val, &txx9_pioptr->dout);
33
}
34
35
static int txx9_gpio_set(struct gpio_chip *chip, unsigned int offset,
36
int value)
37
{
38
unsigned long flags;
39
spin_lock_irqsave(&txx9_gpio_lock, flags);
40
txx9_gpio_set_raw(offset, value);
41
mmiowb();
42
spin_unlock_irqrestore(&txx9_gpio_lock, flags);
43
44
return 0;
45
}
46
47
static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset)
48
{
49
unsigned long flags;
50
spin_lock_irqsave(&txx9_gpio_lock, flags);
51
__raw_writel(__raw_readl(&txx9_pioptr->dir) & ~(1 << offset),
52
&txx9_pioptr->dir);
53
mmiowb();
54
spin_unlock_irqrestore(&txx9_gpio_lock, flags);
55
return 0;
56
}
57
58
static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset,
59
int value)
60
{
61
unsigned long flags;
62
spin_lock_irqsave(&txx9_gpio_lock, flags);
63
txx9_gpio_set_raw(offset, value);
64
__raw_writel(__raw_readl(&txx9_pioptr->dir) | (1 << offset),
65
&txx9_pioptr->dir);
66
mmiowb();
67
spin_unlock_irqrestore(&txx9_gpio_lock, flags);
68
return 0;
69
}
70
71
static struct gpio_chip txx9_gpio_chip = {
72
.get = txx9_gpio_get,
73
.set = txx9_gpio_set,
74
.direction_input = txx9_gpio_dir_in,
75
.direction_output = txx9_gpio_dir_out,
76
.label = "TXx9",
77
};
78
79
int __init txx9_gpio_init(unsigned long baseaddr,
80
unsigned int base, unsigned int num)
81
{
82
txx9_pioptr = ioremap(baseaddr, sizeof(struct txx9_pio_reg));
83
if (!txx9_pioptr)
84
return -ENODEV;
85
txx9_gpio_chip.base = base;
86
txx9_gpio_chip.ngpio = num;
87
return gpiochip_add_data(&txx9_gpio_chip, NULL);
88
}
89
90