hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/pinctrl/pinctrl-at91-pio4.c
....@@ -1,24 +1,14 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Driver for the Atmel PIO4 controller
34 *
45 * Copyright (C) 2015 Atmel,
56 * 2015 Ludovic Desroches <ludovic.desroches@atmel.com>
6
- *
7
- * This software is licensed under the terms of the GNU General Public
8
- * License version 2, as published by the Free Software Foundation, and
9
- * may be copied, distributed, and modified under those terms.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
157 */
168
179 #include <dt-bindings/pinctrl/at91.h>
1810 #include <linux/clk.h>
1911 #include <linux/gpio/driver.h>
20
-/* FIXME: needed for gpio_to_irq(), get rid of this */
21
-#include <linux/gpio.h>
2212 #include <linux/interrupt.h>
2313 #include <linux/io.h>
2414 #include <linux/init.h>
....@@ -116,6 +106,8 @@
116106 * @irq_domain: irq domain for the gpio controller.
117107 * @irqs: table containing the hw irq number of the bank. The index of the
118108 * table is the bank id.
109
+ * @pm_wakeup_sources: bitmap of wakeup sources (lines)
110
+ * @pm_suspend_backup: backup/restore register values on suspend/resume
119111 * @dev: device entry for the Atmel PIO controller.
120112 * @node: node of the Atmel PIO controller.
121113 */
....@@ -264,6 +256,13 @@
264256 .irq_set_wake = atmel_gpio_irq_set_wake,
265257 };
266258
259
+static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
260
+{
261
+ struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
262
+
263
+ return irq_find_mapping(atmel_pioctrl->irq_domain, offset);
264
+}
265
+
267266 static void atmel_gpio_irq_handler(struct irq_desc *desc)
268267 {
269268 unsigned int irq = irq_desc_get_irq(desc);
....@@ -297,8 +296,9 @@
297296 break;
298297
299298 for_each_set_bit(n, &isr, BITS_PER_LONG)
300
- generic_handle_irq(gpio_to_irq(bank *
301
- ATMEL_PIO_NPINS_PER_BANK + n));
299
+ generic_handle_irq(atmel_gpio_to_irq(
300
+ atmel_pioctrl->gpio_chip,
301
+ bank * ATMEL_PIO_NPINS_PER_BANK + n));
302302 }
303303
304304 chained_irq_exit(chip, desc);
....@@ -328,6 +328,33 @@
328328 reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_PDSR);
329329
330330 return !!(reg & BIT(pin->line));
331
+}
332
+
333
+static int atmel_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
334
+ unsigned long *bits)
335
+{
336
+ struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
337
+ unsigned int bank;
338
+
339
+ bitmap_zero(bits, atmel_pioctrl->npins);
340
+
341
+ for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) {
342
+ unsigned int word = bank;
343
+ unsigned int offset = 0;
344
+ unsigned int reg;
345
+
346
+#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
347
+ word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK);
348
+ offset = bank * ATMEL_PIO_NPINS_PER_BANK % BITS_PER_LONG;
349
+#endif
350
+ if (!mask[word])
351
+ continue;
352
+
353
+ reg = atmel_gpio_read(atmel_pioctrl, bank, ATMEL_PIO_PDSR);
354
+ bits[word] |= mask[word] & (reg << offset);
355
+ }
356
+
357
+ return 0;
331358 }
332359
333360 static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
....@@ -360,18 +387,46 @@
360387 BIT(pin->line));
361388 }
362389
363
-static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
390
+static void atmel_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask,
391
+ unsigned long *bits)
364392 {
365393 struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip);
394
+ unsigned int bank;
366395
367
- return irq_find_mapping(atmel_pioctrl->irq_domain, offset);
396
+ for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) {
397
+ unsigned int bitmask;
398
+ unsigned int word = bank;
399
+
400
+/*
401
+ * On a 64-bit platform, BITS_PER_LONG is 64 so it is necessary to iterate over
402
+ * two 32bit words to handle the whole bitmask
403
+ */
404
+#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
405
+ word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK);
406
+#endif
407
+ if (!mask[word])
408
+ continue;
409
+
410
+ bitmask = mask[word] & bits[word];
411
+ atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_SODR, bitmask);
412
+
413
+ bitmask = mask[word] & ~bits[word];
414
+ atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_CODR, bitmask);
415
+
416
+#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG
417
+ mask[word] >>= ATMEL_PIO_NPINS_PER_BANK;
418
+ bits[word] >>= ATMEL_PIO_NPINS_PER_BANK;
419
+#endif
420
+ }
368421 }
369422
370423 static struct gpio_chip atmel_gpio_chip = {
371424 .direction_input = atmel_gpio_direction_input,
372425 .get = atmel_gpio_get,
426
+ .get_multiple = atmel_gpio_get_multiple,
373427 .direction_output = atmel_gpio_direction_output,
374428 .set = atmel_gpio_set,
429
+ .set_multiple = atmel_gpio_set_multiple,
375430 .to_irq = atmel_gpio_to_irq,
376431 .base = 0,
377432 };
....@@ -869,8 +924,7 @@
869924
870925 static int __maybe_unused atmel_pctrl_suspend(struct device *dev)
871926 {
872
- struct platform_device *pdev = to_platform_device(dev);
873
- struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
927
+ struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(dev);
874928 int i, j;
875929
876930 /*
....@@ -898,8 +952,7 @@
898952
899953 static int __maybe_unused atmel_pctrl_resume(struct device *dev)
900954 {
901
- struct platform_device *pdev = to_platform_device(dev);
902
- struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
955
+ struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(dev);
903956 int i, j;
904957
905958 for (i = 0; i < atmel_pioctrl->nbanks; i++) {
....@@ -930,10 +983,17 @@
930983 .nbanks = 4,
931984 };
932985
986
+static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = {
987
+ .nbanks = 5,
988
+};
989
+
933990 static const struct of_device_id atmel_pctrl_of_match[] = {
934991 {
935992 .compatible = "atmel,sama5d2-pinctrl",
936993 .data = &atmel_sama5d2_pioctrl_data,
994
+ }, {
995
+ .compatible = "microchip,sama7g5-pinctrl",
996
+ .data = &microchip_sama7g5_pioctrl_data,
937997 }, {
938998 /* sentinel */
939999 }
....@@ -966,10 +1026,9 @@
9661026 atmel_pioctrl->nbanks = atmel_pioctrl_data->nbanks;
9671027 atmel_pioctrl->npins = atmel_pioctrl->nbanks * ATMEL_PIO_NPINS_PER_BANK;
9681028
969
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
970
- atmel_pioctrl->reg_base = devm_ioremap_resource(dev, res);
1029
+ atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0);
9711030 if (IS_ERR(atmel_pioctrl->reg_base))
972
- return -EINVAL;
1031
+ return PTR_ERR(atmel_pioctrl->reg_base);
9731032
9741033 atmel_pioctrl->clk = devm_clk_get(dev, NULL);
9751034 if (IS_ERR(atmel_pioctrl->clk)) {