hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpio/gpio-tb10x.c
....@@ -1,22 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* Abilis Systems MODULE DESCRIPTION
23 *
34 * Copyright (C) Abilis Systems 2013
45 *
56 * Authors: Sascha Leuenberger <sascha.leuenberger@abilis.com>
67 * Christian Ruppert <christian.ruppert@abilis.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
208 */
219
2210 #include <linux/kernel.h>
....@@ -45,14 +33,12 @@
4533
4634
4735 /**
48
- * @spinlock: used for atomic read/modify/write of registers
4936 * @base: register base address
5037 * @domain: IRQ domain of GPIO generated interrupts managed by this controller
5138 * @irq: Interrupt line of parent interrupt controller
5239 * @gc: gpio_chip structure associated to this GPIO controller
5340 */
5441 struct tb10x_gpio {
55
- spinlock_t spinlock;
5642 void __iomem *base;
5743 struct irq_domain *domain;
5844 int irq;
....@@ -76,60 +62,14 @@
7662 u32 r;
7763 unsigned long flags;
7864
79
- spin_lock_irqsave(&gpio->spinlock, flags);
65
+ spin_lock_irqsave(&gpio->gc.bgpio_lock, flags);
8066
8167 r = tb10x_reg_read(gpio, offs);
8268 r = (r & ~mask) | (val & mask);
8369
8470 tb10x_reg_write(gpio, offs, r);
8571
86
- spin_unlock_irqrestore(&gpio->spinlock, flags);
87
-}
88
-
89
-static int tb10x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
90
-{
91
- struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip);
92
- int mask = BIT(offset);
93
- int val = TB10X_GPIO_DIR_IN << offset;
94
-
95
- tb10x_set_bits(tb10x_gpio, OFFSET_TO_REG_DDR, mask, val);
96
-
97
- return 0;
98
-}
99
-
100
-static int tb10x_gpio_get(struct gpio_chip *chip, unsigned offset)
101
-{
102
- struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip);
103
- int val;
104
-
105
- val = tb10x_reg_read(tb10x_gpio, OFFSET_TO_REG_DATA);
106
-
107
- if (val & BIT(offset))
108
- return 1;
109
- else
110
- return 0;
111
-}
112
-
113
-static void tb10x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
114
-{
115
- struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip);
116
- int mask = BIT(offset);
117
- int val = value << offset;
118
-
119
- tb10x_set_bits(tb10x_gpio, OFFSET_TO_REG_DATA, mask, val);
120
-}
121
-
122
-static int tb10x_gpio_direction_out(struct gpio_chip *chip,
123
- unsigned offset, int value)
124
-{
125
- struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip);
126
- int mask = BIT(offset);
127
- int val = TB10X_GPIO_DIR_OUT << offset;
128
-
129
- tb10x_gpio_set(chip, offset, value);
130
- tb10x_set_bits(tb10x_gpio, OFFSET_TO_REG_DDR, mask, val);
131
-
132
- return 0;
72
+ spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags);
13373 }
13474
13575 static int tb10x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
....@@ -168,73 +108,82 @@
168108 static int tb10x_gpio_probe(struct platform_device *pdev)
169109 {
170110 struct tb10x_gpio *tb10x_gpio;
171
- struct resource *mem;
172
- struct device_node *dn = pdev->dev.of_node;
111
+ struct device *dev = &pdev->dev;
112
+ struct device_node *np = dev->of_node;
173113 int ret = -EBUSY;
174114 u32 ngpio;
175115
176
- if (!dn)
116
+ if (!np)
177117 return -EINVAL;
178118
179
- if (of_property_read_u32(dn, "abilis,ngpio", &ngpio))
119
+ if (of_property_read_u32(np, "abilis,ngpio", &ngpio))
180120 return -EINVAL;
181121
182
- tb10x_gpio = devm_kzalloc(&pdev->dev, sizeof(*tb10x_gpio), GFP_KERNEL);
122
+ tb10x_gpio = devm_kzalloc(dev, sizeof(*tb10x_gpio), GFP_KERNEL);
183123 if (tb10x_gpio == NULL)
184124 return -ENOMEM;
185125
186
- spin_lock_init(&tb10x_gpio->spinlock);
187
-
188
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
189
- tb10x_gpio->base = devm_ioremap_resource(&pdev->dev, mem);
126
+ tb10x_gpio->base = devm_platform_ioremap_resource(pdev, 0);
190127 if (IS_ERR(tb10x_gpio->base))
191128 return PTR_ERR(tb10x_gpio->base);
192129
193
- tb10x_gpio->gc.label =
194
- devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOF", pdev->dev.of_node);
130
+ tb10x_gpio->gc.label =
131
+ devm_kasprintf(dev, GFP_KERNEL, "%pOF", pdev->dev.of_node);
195132 if (!tb10x_gpio->gc.label)
196133 return -ENOMEM;
197134
198
- tb10x_gpio->gc.parent = &pdev->dev;
199
- tb10x_gpio->gc.owner = THIS_MODULE;
200
- tb10x_gpio->gc.direction_input = tb10x_gpio_direction_in;
201
- tb10x_gpio->gc.get = tb10x_gpio_get;
202
- tb10x_gpio->gc.direction_output = tb10x_gpio_direction_out;
203
- tb10x_gpio->gc.set = tb10x_gpio_set;
204
- tb10x_gpio->gc.request = gpiochip_generic_request;
205
- tb10x_gpio->gc.free = gpiochip_generic_free;
206
- tb10x_gpio->gc.base = -1;
207
- tb10x_gpio->gc.ngpio = ngpio;
208
- tb10x_gpio->gc.can_sleep = false;
135
+ /*
136
+ * Initialize generic GPIO with one single register for reading and setting
137
+ * the lines, no special set or clear registers and a data direction register
138
+ * wher 1 means "output".
139
+ */
140
+ ret = bgpio_init(&tb10x_gpio->gc, dev, 4,
141
+ tb10x_gpio->base + OFFSET_TO_REG_DATA,
142
+ NULL,
143
+ NULL,
144
+ tb10x_gpio->base + OFFSET_TO_REG_DDR,
145
+ NULL,
146
+ 0);
147
+ if (ret) {
148
+ dev_err(dev, "unable to init generic GPIO\n");
149
+ return ret;
150
+ }
151
+ tb10x_gpio->gc.base = -1;
152
+ tb10x_gpio->gc.parent = dev;
153
+ tb10x_gpio->gc.owner = THIS_MODULE;
154
+ /*
155
+ * ngpio is set by bgpio_init() but we override it, this .request()
156
+ * callback also overrides the one set up by generic GPIO.
157
+ */
158
+ tb10x_gpio->gc.ngpio = ngpio;
159
+ tb10x_gpio->gc.request = gpiochip_generic_request;
160
+ tb10x_gpio->gc.free = gpiochip_generic_free;
209161
210
-
211
- ret = devm_gpiochip_add_data(&pdev->dev, &tb10x_gpio->gc, tb10x_gpio);
162
+ ret = devm_gpiochip_add_data(dev, &tb10x_gpio->gc, tb10x_gpio);
212163 if (ret < 0) {
213
- dev_err(&pdev->dev, "Could not add gpiochip.\n");
164
+ dev_err(dev, "Could not add gpiochip.\n");
214165 return ret;
215166 }
216167
217168 platform_set_drvdata(pdev, tb10x_gpio);
218169
219
- if (of_find_property(dn, "interrupt-controller", NULL)) {
170
+ if (of_find_property(np, "interrupt-controller", NULL)) {
220171 struct irq_chip_generic *gc;
221172
222173 ret = platform_get_irq(pdev, 0);
223
- if (ret < 0) {
224
- dev_err(&pdev->dev, "No interrupt specified.\n");
174
+ if (ret < 0)
225175 return ret;
226
- }
227176
228177 tb10x_gpio->gc.to_irq = tb10x_gpio_to_irq;
229178 tb10x_gpio->irq = ret;
230179
231
- ret = devm_request_irq(&pdev->dev, ret, tb10x_gpio_irq_cascade,
180
+ ret = devm_request_irq(dev, ret, tb10x_gpio_irq_cascade,
232181 IRQF_TRIGGER_NONE | IRQF_SHARED,
233
- dev_name(&pdev->dev), tb10x_gpio);
182
+ dev_name(dev), tb10x_gpio);
234183 if (ret != 0)
235184 return ret;
236185
237
- tb10x_gpio->domain = irq_domain_add_linear(dn,
186
+ tb10x_gpio->domain = irq_domain_add_linear(np,
238187 tb10x_gpio->gc.ngpio,
239188 &irq_generic_chip_ops, NULL);
240189 if (!tb10x_gpio->domain) {
....@@ -294,4 +243,3 @@
294243 module_platform_driver(tb10x_gpio_driver);
295244 MODULE_LICENSE("GPL");
296245 MODULE_DESCRIPTION("tb10x gpio.");
297
-MODULE_VERSION("0.0.1");