From d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 02:45:28 +0000 Subject: [PATCH] add boot partition size --- kernel/drivers/pinctrl/pinctrl-at91-pio4.c | 103 ++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 81 insertions(+), 22 deletions(-) diff --git a/kernel/drivers/pinctrl/pinctrl-at91-pio4.c b/kernel/drivers/pinctrl/pinctrl-at91-pio4.c index 9e2f373..578b387 100644 --- a/kernel/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/kernel/drivers/pinctrl/pinctrl-at91-pio4.c @@ -1,24 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Driver for the Atmel PIO4 controller * * Copyright (C) 2015 Atmel, * 2015 Ludovic Desroches <ludovic.desroches@atmel.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <dt-bindings/pinctrl/at91.h> #include <linux/clk.h> #include <linux/gpio/driver.h> -/* FIXME: needed for gpio_to_irq(), get rid of this */ -#include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/init.h> @@ -116,6 +106,8 @@ * @irq_domain: irq domain for the gpio controller. * @irqs: table containing the hw irq number of the bank. The index of the * table is the bank id. + * @pm_wakeup_sources: bitmap of wakeup sources (lines) + * @pm_suspend_backup: backup/restore register values on suspend/resume * @dev: device entry for the Atmel PIO controller. * @node: node of the Atmel PIO controller. */ @@ -264,6 +256,13 @@ .irq_set_wake = atmel_gpio_irq_set_wake, }; +static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); + + return irq_find_mapping(atmel_pioctrl->irq_domain, offset); +} + static void atmel_gpio_irq_handler(struct irq_desc *desc) { unsigned int irq = irq_desc_get_irq(desc); @@ -297,8 +296,9 @@ break; for_each_set_bit(n, &isr, BITS_PER_LONG) - generic_handle_irq(gpio_to_irq(bank * - ATMEL_PIO_NPINS_PER_BANK + n)); + generic_handle_irq(atmel_gpio_to_irq( + atmel_pioctrl->gpio_chip, + bank * ATMEL_PIO_NPINS_PER_BANK + n)); } chained_irq_exit(chip, desc); @@ -328,6 +328,33 @@ reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_PDSR); return !!(reg & BIT(pin->line)); +} + +static int atmel_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, + unsigned long *bits) +{ + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); + unsigned int bank; + + bitmap_zero(bits, atmel_pioctrl->npins); + + for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) { + unsigned int word = bank; + unsigned int offset = 0; + unsigned int reg; + +#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG + word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK); + offset = bank * ATMEL_PIO_NPINS_PER_BANK % BITS_PER_LONG; +#endif + if (!mask[word]) + continue; + + reg = atmel_gpio_read(atmel_pioctrl, bank, ATMEL_PIO_PDSR); + bits[word] |= mask[word] & (reg << offset); + } + + return 0; } static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset, @@ -360,18 +387,46 @@ BIT(pin->line)); } -static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +static void atmel_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask, + unsigned long *bits) { struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); + unsigned int bank; - return irq_find_mapping(atmel_pioctrl->irq_domain, offset); + for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) { + unsigned int bitmask; + unsigned int word = bank; + +/* + * On a 64-bit platform, BITS_PER_LONG is 64 so it is necessary to iterate over + * two 32bit words to handle the whole bitmask + */ +#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG + word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK); +#endif + if (!mask[word]) + continue; + + bitmask = mask[word] & bits[word]; + atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_SODR, bitmask); + + bitmask = mask[word] & ~bits[word]; + atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_CODR, bitmask); + +#if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG + mask[word] >>= ATMEL_PIO_NPINS_PER_BANK; + bits[word] >>= ATMEL_PIO_NPINS_PER_BANK; +#endif + } } static struct gpio_chip atmel_gpio_chip = { .direction_input = atmel_gpio_direction_input, .get = atmel_gpio_get, + .get_multiple = atmel_gpio_get_multiple, .direction_output = atmel_gpio_direction_output, .set = atmel_gpio_set, + .set_multiple = atmel_gpio_set_multiple, .to_irq = atmel_gpio_to_irq, .base = 0, }; @@ -869,8 +924,7 @@ static int __maybe_unused atmel_pctrl_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev); + struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(dev); int i, j; /* @@ -898,8 +952,7 @@ static int __maybe_unused atmel_pctrl_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev); + struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(dev); int i, j; for (i = 0; i < atmel_pioctrl->nbanks; i++) { @@ -930,10 +983,17 @@ .nbanks = 4, }; +static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = { + .nbanks = 5, +}; + static const struct of_device_id atmel_pctrl_of_match[] = { { .compatible = "atmel,sama5d2-pinctrl", .data = &atmel_sama5d2_pioctrl_data, + }, { + .compatible = "microchip,sama7g5-pinctrl", + .data = µchip_sama7g5_pioctrl_data, }, { /* sentinel */ } @@ -966,10 +1026,9 @@ atmel_pioctrl->nbanks = atmel_pioctrl_data->nbanks; atmel_pioctrl->npins = atmel_pioctrl->nbanks * ATMEL_PIO_NPINS_PER_BANK; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - atmel_pioctrl->reg_base = devm_ioremap_resource(dev, res); + atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(atmel_pioctrl->reg_base)) - return -EINVAL; + return PTR_ERR(atmel_pioctrl->reg_base); atmel_pioctrl->clk = devm_clk_get(dev, NULL); if (IS_ERR(atmel_pioctrl->clk)) { -- Gitblit v1.6.2