diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/kernel/gpio_txx9.c | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/kernel/gpio_txx9.c')
-rw-r--r-- | arch/mips/kernel/gpio_txx9.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/arch/mips/kernel/gpio_txx9.c b/arch/mips/kernel/gpio_txx9.c new file mode 100644 index 000000000..8c083612d --- /dev/null +++ b/arch/mips/kernel/gpio_txx9.c | |||
@@ -0,0 +1,86 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * A gpio chip driver for TXx9 SoCs | ||
4 | * | ||
5 | * Copyright (C) 2008 Atsushi Nemoto <anemo@mba.ocn.ne.jp> | ||
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 void 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 | |||
45 | static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset) | ||
46 | { | ||
47 | unsigned long flags; | ||
48 | spin_lock_irqsave(&txx9_gpio_lock, flags); | ||
49 | __raw_writel(__raw_readl(&txx9_pioptr->dir) & ~(1 << offset), | ||
50 | &txx9_pioptr->dir); | ||
51 | mmiowb(); | ||
52 | spin_unlock_irqrestore(&txx9_gpio_lock, flags); | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset, | ||
57 | int value) | ||
58 | { | ||
59 | unsigned long flags; | ||
60 | spin_lock_irqsave(&txx9_gpio_lock, flags); | ||
61 | txx9_gpio_set_raw(offset, value); | ||
62 | __raw_writel(__raw_readl(&txx9_pioptr->dir) | (1 << offset), | ||
63 | &txx9_pioptr->dir); | ||
64 | mmiowb(); | ||
65 | spin_unlock_irqrestore(&txx9_gpio_lock, flags); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static struct gpio_chip txx9_gpio_chip = { | ||
70 | .get = txx9_gpio_get, | ||
71 | .set = txx9_gpio_set, | ||
72 | .direction_input = txx9_gpio_dir_in, | ||
73 | .direction_output = txx9_gpio_dir_out, | ||
74 | .label = "TXx9", | ||
75 | }; | ||
76 | |||
77 | int __init txx9_gpio_init(unsigned long baseaddr, | ||
78 | unsigned int base, unsigned int num) | ||
79 | { | ||
80 | txx9_pioptr = ioremap(baseaddr, sizeof(struct txx9_pio_reg)); | ||
81 | if (!txx9_pioptr) | ||
82 | return -ENODEV; | ||
83 | txx9_gpio_chip.base = base; | ||
84 | txx9_gpio_chip.ngpio = num; | ||
85 | return gpiochip_add_data(&txx9_gpio_chip, NULL); | ||
86 | } | ||