^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2015 IBM Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Joel Stanley <joel@jms.id.au>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/gpio/aspeed.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/hashtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pinctrl/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * These two headers aren't meant to be used by GPIO drivers. We need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * them in order to access gpio_chip_hwgpio() which we need to implement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * the aspeed specific API which allows the coprocessor to request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * access to some GPIOs and to arbitrate between coprocessor and ARM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "gpiolib.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct aspeed_bank_props {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned int bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u32 output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct aspeed_gpio_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned int nr_gpios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) const struct aspeed_bank_props *props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @offset_timer: Maps an offset to an @timer_users index, or zero if disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @timer_users: Tracks the number of users for each timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * The @timer_users has four elements but the first element is unused. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * to simplify accounting and indexing, as a zero value in @offset_timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * represents disabled debouncing for the GPIO. Any other value for an element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * of @offset_timer is used as an index into @timer_users. This behaviour of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * the zero value aligns with the behaviour of zero built from the timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * configuration registers (i.e. debouncing is disabled).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct aspeed_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct irq_chip irqc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) raw_spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) const struct aspeed_gpio_config *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u8 *offset_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int timer_users[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u32 *dcache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u8 *cf_copro_bankmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct aspeed_gpio_bank {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) uint16_t val_regs; /* +0: Rd: read input value, Wr: set write latch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * +4: Rd/Wr: Direction (0=in, 1=out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) uint16_t rdata_reg; /* Rd: read write latch, Wr: <none> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) uint16_t irq_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) uint16_t debounce_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) uint16_t tolerance_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) uint16_t cmdsrc_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) const char names[4][3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Note: The "value" register returns the input value sampled on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * line even when the GPIO is configured as an output. Since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * that input goes through synchronizers, writing, then reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * back may not return the written value right away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * The "rdata" register returns the content of the write latch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * and thus can be used to read back what was last written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * reliably.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static const int debounce_timers[4] = { 0x00, 0x50, 0x54, 0x58 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static const struct aspeed_gpio_copro_ops *copro_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void *copro_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .val_regs = 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .rdata_reg = 0x00c0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .irq_regs = 0x0008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .debounce_regs = 0x0040,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .tolerance_regs = 0x001c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .cmdsrc_regs = 0x0060,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .names = { "A", "B", "C", "D" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .val_regs = 0x0020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .rdata_reg = 0x00c4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .irq_regs = 0x0028,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .debounce_regs = 0x0048,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .tolerance_regs = 0x003c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .cmdsrc_regs = 0x0068,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .names = { "E", "F", "G", "H" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .val_regs = 0x0070,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .rdata_reg = 0x00c8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .irq_regs = 0x0098,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .debounce_regs = 0x00b0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .tolerance_regs = 0x00ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .cmdsrc_regs = 0x0090,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .names = { "I", "J", "K", "L" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .val_regs = 0x0078,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .rdata_reg = 0x00cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .irq_regs = 0x00e8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .debounce_regs = 0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .tolerance_regs = 0x00fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .cmdsrc_regs = 0x00e0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .names = { "M", "N", "O", "P" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .val_regs = 0x0080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .rdata_reg = 0x00d0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .irq_regs = 0x0118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .debounce_regs = 0x0130,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .tolerance_regs = 0x012c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .cmdsrc_regs = 0x0110,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .names = { "Q", "R", "S", "T" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .val_regs = 0x0088,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .rdata_reg = 0x00d4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .irq_regs = 0x0148,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .debounce_regs = 0x0160,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .tolerance_regs = 0x015c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .cmdsrc_regs = 0x0140,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .names = { "U", "V", "W", "X" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .val_regs = 0x01E0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .rdata_reg = 0x00d8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .irq_regs = 0x0178,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .debounce_regs = 0x0190,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .tolerance_regs = 0x018c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .cmdsrc_regs = 0x0170,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .names = { "Y", "Z", "AA", "AB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .val_regs = 0x01e8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .rdata_reg = 0x00dc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .irq_regs = 0x01a8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .debounce_regs = 0x01c0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .tolerance_regs = 0x01bc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .cmdsrc_regs = 0x01a0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .names = { "AC", "", "", "" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) enum aspeed_gpio_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) reg_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) reg_rdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) reg_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) reg_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) reg_irq_type0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) reg_irq_type1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) reg_irq_type2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) reg_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) reg_debounce_sel1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) reg_debounce_sel2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) reg_tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) reg_cmdsrc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) reg_cmdsrc1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define GPIO_VAL_VALUE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define GPIO_VAL_DIR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define GPIO_IRQ_ENABLE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define GPIO_IRQ_TYPE0 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define GPIO_IRQ_TYPE1 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define GPIO_IRQ_TYPE2 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define GPIO_IRQ_STATUS 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define GPIO_DEBOUNCE_SEL1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define GPIO_DEBOUNCE_SEL2 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define GPIO_CMDSRC_0 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define GPIO_CMDSRC_1 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define GPIO_CMDSRC_ARM 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define GPIO_CMDSRC_LPC 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define GPIO_CMDSRC_COLDFIRE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define GPIO_CMDSRC_RESERVED 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* This will be resolved at compile time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static inline void __iomem *bank_reg(struct aspeed_gpio *gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) const struct aspeed_gpio_bank *bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) const enum aspeed_gpio_reg reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case reg_val:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return gpio->base + bank->val_regs + GPIO_VAL_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case reg_rdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return gpio->base + bank->rdata_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case reg_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return gpio->base + bank->val_regs + GPIO_VAL_DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case reg_irq_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return gpio->base + bank->irq_regs + GPIO_IRQ_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case reg_irq_type0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case reg_irq_type1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case reg_irq_type2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case reg_irq_status:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case reg_debounce_sel1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return gpio->base + bank->debounce_regs + GPIO_DEBOUNCE_SEL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) case reg_debounce_sel2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return gpio->base + bank->debounce_regs + GPIO_DEBOUNCE_SEL2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case reg_tolerance:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return gpio->base + bank->tolerance_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case reg_cmdsrc0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return gpio->base + bank->cmdsrc_regs + GPIO_CMDSRC_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case reg_cmdsrc1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return gpio->base + bank->cmdsrc_regs + GPIO_CMDSRC_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define GPIO_BANK(x) ((x) >> 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define GPIO_OFFSET(x) ((x) & 0x1f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define GPIO_BIT(x) BIT(GPIO_OFFSET(x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define _GPIO_SET_DEBOUNCE(t, o, i) ((!!((t) & BIT(i))) << GPIO_OFFSET(o))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define GPIO_SET_DEBOUNCE1(t, o) _GPIO_SET_DEBOUNCE(t, o, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define GPIO_SET_DEBOUNCE2(t, o) _GPIO_SET_DEBOUNCE(t, o, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static const struct aspeed_gpio_bank *to_bank(unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned int bank = GPIO_BANK(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) WARN_ON(bank >= ARRAY_SIZE(aspeed_gpio_banks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return &aspeed_gpio_banks[bank];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static inline bool is_bank_props_sentinel(const struct aspeed_bank_props *props)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return !(props->input || props->output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static inline const struct aspeed_bank_props *find_bank_props(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct aspeed_gpio *gpio, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) const struct aspeed_bank_props *props = gpio->config->props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) while (!is_bank_props_sentinel(props)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (props->bank == GPIO_BANK(offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) props++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static inline bool have_gpio(struct aspeed_gpio *gpio, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) const struct aspeed_bank_props *props = find_bank_props(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) unsigned int group = GPIO_OFFSET(offset) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return bank->names[group][0] != '\0' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) (!props || ((props->input | props->output) & GPIO_BIT(offset)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static inline bool have_input(struct aspeed_gpio *gpio, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) const struct aspeed_bank_props *props = find_bank_props(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return !props || (props->input & GPIO_BIT(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #define have_irq(g, o) have_input((g), (o))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #define have_debounce(g, o) have_input((g), (o))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static inline bool have_output(struct aspeed_gpio *gpio, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) const struct aspeed_bank_props *props = find_bank_props(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return !props || (props->output & GPIO_BIT(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static void aspeed_gpio_change_cmd_source(struct aspeed_gpio *gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) const struct aspeed_gpio_bank *bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int bindex, int cmdsrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) void __iomem *c0 = bank_reg(gpio, bank, reg_cmdsrc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) void __iomem *c1 = bank_reg(gpio, bank, reg_cmdsrc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u32 bit, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * Each register controls 4 banks, so take the bottom 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * bits of the bank index, and use them to select the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * right control bit (0, 8, 16 or 24).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) bit = BIT((bindex & 3) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Source 1 first to avoid illegal 11 combination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) reg = ioread32(c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (cmdsrc & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) reg |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) reg &= ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) iowrite32(reg, c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Then Source 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) reg = ioread32(c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (cmdsrc & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) reg |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) reg &= ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) iowrite32(reg, c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static bool aspeed_gpio_copro_request(struct aspeed_gpio *gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (!copro_ops || !gpio->cf_copro_bankmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (!gpio->cf_copro_bankmap[offset >> 3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (!copro_ops->request_access)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* Pause the coprocessor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) copro_ops->request_access(copro_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* Change command source back to ARM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) aspeed_gpio_change_cmd_source(gpio, bank, offset >> 3, GPIO_CMDSRC_ARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Update cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) gpio->dcache[GPIO_BANK(offset)] = ioread32(bank_reg(gpio, bank, reg_rdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static void aspeed_gpio_copro_release(struct aspeed_gpio *gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!copro_ops || !gpio->cf_copro_bankmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!gpio->cf_copro_bankmap[offset >> 3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (!copro_ops->release_access)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* Change command source back to ColdFire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) aspeed_gpio_change_cmd_source(gpio, bank, offset >> 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) GPIO_CMDSRC_COLDFIRE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Restart the coprocessor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) copro_ops->release_access(copro_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int aspeed_gpio_get(struct gpio_chip *gc, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct aspeed_gpio *gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return !!(ioread32(bank_reg(gpio, bank, reg_val)) & GPIO_BIT(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct aspeed_gpio *gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) addr = bank_reg(gpio, bank, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) reg = gpio->dcache[GPIO_BANK(offset)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) reg |= GPIO_BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) reg &= ~GPIO_BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) gpio->dcache[GPIO_BANK(offset)] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) iowrite32(reg, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct aspeed_gpio *gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) bool copro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) copro = aspeed_gpio_copro_request(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) __aspeed_gpio_set(gc, offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (copro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) aspeed_gpio_copro_release(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct aspeed_gpio *gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) void __iomem *addr = bank_reg(gpio, bank, reg_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) bool copro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (!have_input(gpio, offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) reg = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) reg &= ~GPIO_BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) copro = aspeed_gpio_copro_request(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) iowrite32(reg, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (copro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) aspeed_gpio_copro_release(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int aspeed_gpio_dir_out(struct gpio_chip *gc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) unsigned int offset, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct aspeed_gpio *gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) void __iomem *addr = bank_reg(gpio, bank, reg_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) bool copro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (!have_output(gpio, offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) reg = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) reg |= GPIO_BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) copro = aspeed_gpio_copro_request(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) __aspeed_gpio_set(gc, offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) iowrite32(reg, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (copro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) aspeed_gpio_copro_release(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct aspeed_gpio *gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (!have_input(gpio, offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return GPIO_LINE_DIRECTION_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!have_output(gpio, offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return GPIO_LINE_DIRECTION_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) val = ioread32(bank_reg(gpio, bank, reg_dir)) & GPIO_BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return val ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static inline int irqd_to_aspeed_gpio_data(struct irq_data *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct aspeed_gpio **gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) const struct aspeed_gpio_bank **bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u32 *bit, int *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct aspeed_gpio *internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) *offset = irqd_to_hwirq(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) internal = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* This might be a bit of a questionable place to check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (!have_irq(internal, *offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) *gpio = internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) *bank = to_bank(*offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) *bit = GPIO_BIT(*offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void aspeed_gpio_irq_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) const struct aspeed_gpio_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct aspeed_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) void __iomem *status_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int rc, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) bool copro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) u32 bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) rc = irqd_to_aspeed_gpio_data(d, &gpio, &bank, &bit, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) status_addr = bank_reg(gpio, bank, reg_irq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) copro = aspeed_gpio_copro_request(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) iowrite32(bit, status_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (copro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) aspeed_gpio_copro_release(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) const struct aspeed_gpio_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct aspeed_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) u32 reg, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int rc, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) bool copro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) rc = irqd_to_aspeed_gpio_data(d, &gpio, &bank, &bit, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) addr = bank_reg(gpio, bank, reg_irq_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) copro = aspeed_gpio_copro_request(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) reg = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) reg |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) reg &= ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) iowrite32(reg, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (copro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) aspeed_gpio_copro_release(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static void aspeed_gpio_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) aspeed_gpio_irq_set_mask(d, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static void aspeed_gpio_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) aspeed_gpio_irq_set_mask(d, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) u32 type0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) u32 type1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) u32 type2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) u32 bit, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) const struct aspeed_gpio_bank *bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) irq_flow_handler_t handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct aspeed_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) int rc, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) bool copro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) rc = irqd_to_aspeed_gpio_data(d, &gpio, &bank, &bit, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) switch (type & IRQ_TYPE_SENSE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) type2 |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) type0 |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) handler = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) type0 |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) type1 |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) handler = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) copro = aspeed_gpio_copro_request(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) addr = bank_reg(gpio, bank, reg_irq_type0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) reg = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) reg = (reg & ~bit) | type0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) iowrite32(reg, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) addr = bank_reg(gpio, bank, reg_irq_type1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) reg = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) reg = (reg & ~bit) | type1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) iowrite32(reg, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) addr = bank_reg(gpio, bank, reg_irq_type2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) reg = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) reg = (reg & ~bit) | type2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) iowrite32(reg, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (copro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) aspeed_gpio_copro_release(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) irq_set_handler_locked(d, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static void aspeed_gpio_irq_handler(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct gpio_chip *gc = irq_desc_get_handler_data(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct irq_chip *ic = irq_desc_get_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct aspeed_gpio *data = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) unsigned int i, p, girq, banks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) unsigned long reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct aspeed_gpio *gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) chained_irq_enter(ic, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) banks = DIV_ROUND_UP(gpio->chip.ngpio, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) for (i = 0; i < banks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) const struct aspeed_gpio_bank *bank = &aspeed_gpio_banks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) reg = ioread32(bank_reg(data, bank, reg_irq_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) for_each_set_bit(p, ®, 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) girq = irq_find_mapping(gc->irq.domain, i * 32 + p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) generic_handle_irq(girq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) chained_irq_exit(ic, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static void aspeed_init_irq_valid_mask(struct gpio_chip *gc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) unsigned long *valid_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) unsigned int ngpios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct aspeed_gpio *gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) const struct aspeed_bank_props *props = gpio->config->props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) while (!is_bank_props_sentinel(props)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) const unsigned long int input = props->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* Pretty crummy approach, but similar to GPIO core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) for_each_clear_bit(offset, &input, 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) unsigned int i = props->bank * 32 + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (i >= gpio->chip.ngpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) clear_bit(i, valid_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) props++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) unsigned int offset, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct aspeed_gpio *gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) void __iomem *treg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) bool copro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) treg = bank_reg(gpio, to_bank(offset), reg_tolerance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) copro = aspeed_gpio_copro_request(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) val = readl(treg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) val |= GPIO_BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) val &= ~GPIO_BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) writel(val, treg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (copro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) aspeed_gpio_copro_release(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static int aspeed_gpio_request(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!have_gpio(gpiochip_get_data(chip), offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return pinctrl_gpio_request(chip->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static void aspeed_gpio_free(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) pinctrl_gpio_free(chip->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static int usecs_to_cycles(struct aspeed_gpio *gpio, unsigned long usecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) u32 *cycles)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) u64 rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) u64 n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u32 r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) rate = clk_get_rate(gpio->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) n = rate * usecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) r = do_div(n, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (n >= U32_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* At least as long as the requested time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) *cycles = n + (!!r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /* Call under gpio->lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static int register_allocated_timer(struct aspeed_gpio *gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) unsigned int offset, unsigned int timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (WARN(gpio->offset_timer[offset] != 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) "Offset %d already allocated timer %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) offset, gpio->offset_timer[offset]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (WARN(gpio->timer_users[timer] == UINT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) "Timer user count would overflow\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) gpio->offset_timer[offset] = timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) gpio->timer_users[timer]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* Call under gpio->lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static int unregister_allocated_timer(struct aspeed_gpio *gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (WARN(gpio->offset_timer[offset] == 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) "No timer allocated to offset %d\n", offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (WARN(gpio->timer_users[gpio->offset_timer[offset]] == 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) "No users recorded for timer %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) gpio->offset_timer[offset]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) gpio->timer_users[gpio->offset_timer[offset]]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) gpio->offset_timer[offset] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* Call under gpio->lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static inline bool timer_allocation_registered(struct aspeed_gpio *gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return gpio->offset_timer[offset] > 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* Call under gpio->lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static void configure_timer(struct aspeed_gpio *gpio, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) unsigned int timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) const u32 mask = GPIO_BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* Note: Debounce timer isn't under control of the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * source registers, so no need to sync with the coprocessor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) addr = bank_reg(gpio, bank, reg_debounce_sel1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) val = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) iowrite32((val & ~mask) | GPIO_SET_DEBOUNCE1(timer, offset), addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) addr = bank_reg(gpio, bank, reg_debounce_sel2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) val = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) iowrite32((val & ~mask) | GPIO_SET_DEBOUNCE2(timer, offset), addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) unsigned long usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct aspeed_gpio *gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) u32 requested_cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (!gpio->clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) rc = usecs_to_cycles(gpio, usecs, &requested_cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) dev_warn(chip->parent, "Failed to convert %luus to cycles at %luHz: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) usecs, clk_get_rate(gpio->clk), rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (timer_allocation_registered(gpio, offset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) rc = unregister_allocated_timer(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /* Try to find a timer already configured for the debounce period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) for (i = 1; i < ARRAY_SIZE(debounce_timers); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) u32 cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) cycles = ioread32(gpio->base + debounce_timers[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (requested_cycles == cycles)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (i == ARRAY_SIZE(debounce_timers)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * As there are no timers configured for the requested debounce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * period, find an unused timer instead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) for (j = 1; j < ARRAY_SIZE(gpio->timer_users); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (gpio->timer_users[j] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (j == ARRAY_SIZE(gpio->timer_users)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev_warn(chip->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) "Debounce timers exhausted, cannot debounce for period %luus\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) usecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * We already adjusted the accounting to remove @offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * as a user of its previous timer, so also configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * the hardware so @offset has timers disabled for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * consistency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) configure_timer(gpio, offset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) i = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) iowrite32(requested_cycles, gpio->base + debounce_timers[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (WARN(i == 0, "Cannot register index of disabled timer\n")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) register_allocated_timer(gpio, offset, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) configure_timer(gpio, offset, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static int disable_debounce(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct aspeed_gpio *gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) rc = unregister_allocated_timer(gpio, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) configure_timer(gpio, offset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static int set_debounce(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) unsigned long usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct aspeed_gpio *gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (!have_debounce(gpio, offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return enable_debounce(chip, offset, usecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return disable_debounce(chip, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static int aspeed_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) unsigned long config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) unsigned long param = pinconf_to_config_param(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) u32 arg = pinconf_to_config_argument(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (param == PIN_CONFIG_INPUT_DEBOUNCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return set_debounce(chip, offset, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) else if (param == PIN_CONFIG_BIAS_DISABLE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) param == PIN_CONFIG_BIAS_PULL_DOWN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) param == PIN_CONFIG_DRIVE_STRENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return pinctrl_gpio_set_config(offset, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) else if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) param == PIN_CONFIG_DRIVE_OPEN_SOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* Return -ENOTSUPP to trigger emulation, as per datasheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) else if (param == PIN_CONFIG_PERSIST_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return aspeed_gpio_reset_tolerance(chip, offset, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * aspeed_gpio_copro_set_ops - Sets the callbacks used for handshaking with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) * the coprocessor for shared GPIO banks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * @ops: The callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * @data: Pointer passed back to the callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) int aspeed_gpio_copro_set_ops(const struct aspeed_gpio_copro_ops *ops, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) copro_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) copro_ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) EXPORT_SYMBOL_GPL(aspeed_gpio_copro_set_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * aspeed_gpio_copro_grab_gpio - Mark a GPIO used by the coprocessor. The entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * bank gets marked and any access from the ARM will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * result in handshaking via callbacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * @desc: The GPIO to be marked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * @vreg_offset: If non-NULL, returns the value register offset in the GPIO space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * @dreg_offset: If non-NULL, returns the data latch register offset in the GPIO space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * @bit: If non-NULL, returns the bit number of the GPIO in the registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) u16 *vreg_offset, u16 *dreg_offset, u8 *bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct gpio_chip *chip = gpiod_to_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) struct aspeed_gpio *gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) int rc = 0, bindex, offset = gpio_chip_hwgpio(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (!gpio->cf_copro_bankmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) gpio->cf_copro_bankmap = kzalloc(gpio->chip.ngpio >> 3, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (!gpio->cf_copro_bankmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (offset < 0 || offset > gpio->chip.ngpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) bindex = offset >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* Sanity check, this shouldn't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (gpio->cf_copro_bankmap[bindex] == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) gpio->cf_copro_bankmap[bindex]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* Switch command source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (gpio->cf_copro_bankmap[bindex] == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) aspeed_gpio_change_cmd_source(gpio, bank, bindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) GPIO_CMDSRC_COLDFIRE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (vreg_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) *vreg_offset = bank->val_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (dreg_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) *dreg_offset = bank->rdata_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *bit = GPIO_OFFSET(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * aspeed_gpio_copro_release_gpio - Unmark a GPIO used by the coprocessor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * @desc: The GPIO to be marked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) struct gpio_chip *chip = gpiod_to_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct aspeed_gpio *gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) int rc = 0, bindex, offset = gpio_chip_hwgpio(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) const struct aspeed_gpio_bank *bank = to_bank(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (!gpio->cf_copro_bankmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (offset < 0 || offset > gpio->chip.ngpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) bindex = offset >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) raw_spin_lock_irqsave(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /* Sanity check, this shouldn't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (gpio->cf_copro_bankmap[bindex] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) gpio->cf_copro_bankmap[bindex]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /* Switch command source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (gpio->cf_copro_bankmap[bindex] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) aspeed_gpio_change_cmd_source(gpio, bank, bindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) GPIO_CMDSRC_ARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) bail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) raw_spin_unlock_irqrestore(&gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * Any banks not specified in a struct aspeed_bank_props array are assumed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * have the properties:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) * { .input = 0xffffffff, .output = 0xffffffff }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static const struct aspeed_bank_props ast2400_bank_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /* input output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) { 5, 0xffffffff, 0x0000ffff }, /* U/V/W/X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) { 6, 0x0000000f, 0x0fffff0f }, /* Y/Z/AA/AB, two 4-GPIO holes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static const struct aspeed_gpio_config ast2400_config =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /* 220 for simplicity, really 216 with two 4-GPIO holes, four at end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) { .nr_gpios = 220, .props = ast2400_bank_props, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static const struct aspeed_bank_props ast2500_bank_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) /* input output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) { 5, 0xffffffff, 0x0000ffff }, /* U/V/W/X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) { 6, 0x0fffffff, 0x0fffffff }, /* Y/Z/AA/AB, 4-GPIO hole */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) { 7, 0x000000ff, 0x000000ff }, /* AC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) static const struct aspeed_gpio_config ast2500_config =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* 232 for simplicity, actual number is 228 (4-GPIO hole in GPIOAB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) { .nr_gpios = 232, .props = ast2500_bank_props, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) static const struct aspeed_bank_props ast2600_bank_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /* input output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) {4, 0xffffffff, 0x00ffffff}, /* Q/R/S/T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) {5, 0xffffffff, 0xffffff00}, /* U/V/W/X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {6, 0x0000ffff, 0x0000ffff}, /* Y/Z */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static const struct aspeed_gpio_config ast2600_config =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * ast2600 has two controllers one with 208 GPIOs and one with 36 GPIOs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * We expect ngpio being set in the device tree and this is a fallback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) { .nr_gpios = 208, .props = ast2600_bank_props, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static const struct of_device_id aspeed_gpio_of_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) { .compatible = "aspeed,ast2400-gpio", .data = &ast2400_config, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) { .compatible = "aspeed,ast2500-gpio", .data = &ast2500_config, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) { .compatible = "aspeed,ast2600-gpio", .data = &ast2600_config, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) MODULE_DEVICE_TABLE(of, aspeed_gpio_of_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) static int __init aspeed_gpio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) const struct of_device_id *gpio_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) struct aspeed_gpio *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) int rc, i, banks, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) u32 ngpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (!gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) gpio->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (IS_ERR(gpio->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return PTR_ERR(gpio->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) raw_spin_lock_init(&gpio->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (!gpio_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) gpio->clk = of_clk_get(pdev->dev.of_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (IS_ERR(gpio->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) "Failed to get clock from devicetree, debouncing disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) gpio->clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) gpio->config = gpio_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) gpio->chip.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) err = of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) gpio->chip.ngpio = (u16) ngpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) gpio->chip.ngpio = gpio->config->nr_gpios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) gpio->chip.direction_input = aspeed_gpio_dir_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) gpio->chip.direction_output = aspeed_gpio_dir_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) gpio->chip.get_direction = aspeed_gpio_get_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) gpio->chip.request = aspeed_gpio_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) gpio->chip.free = aspeed_gpio_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) gpio->chip.get = aspeed_gpio_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) gpio->chip.set = aspeed_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) gpio->chip.set_config = aspeed_gpio_set_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) gpio->chip.label = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) gpio->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* Allocate a cache of the output registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) banks = DIV_ROUND_UP(gpio->chip.ngpio, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) gpio->dcache = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) banks, sizeof(u32), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (!gpio->dcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * Populate it with initial values read from the HW and switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * all command sources to the ARM by default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) for (i = 0; i < banks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) const struct aspeed_gpio_bank *bank = &aspeed_gpio_banks[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) void __iomem *addr = bank_reg(gpio, bank, reg_rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) gpio->dcache[i] = ioread32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) aspeed_gpio_change_cmd_source(gpio, bank, 0, GPIO_CMDSRC_ARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) aspeed_gpio_change_cmd_source(gpio, bank, 1, GPIO_CMDSRC_ARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) aspeed_gpio_change_cmd_source(gpio, bank, 2, GPIO_CMDSRC_ARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) aspeed_gpio_change_cmd_source(gpio, bank, 3, GPIO_CMDSRC_ARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) /* Optionally set up an irqchip if there is an IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) rc = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (rc > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) struct gpio_irq_chip *girq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) gpio->irq = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) girq = &gpio->chip.irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) girq->chip = &gpio->irqc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) girq->chip->name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) girq->chip->irq_ack = aspeed_gpio_irq_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) girq->chip->irq_mask = aspeed_gpio_irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) girq->chip->irq_unmask = aspeed_gpio_irq_unmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) girq->chip->irq_set_type = aspeed_gpio_set_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) girq->parent_handler = aspeed_gpio_irq_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) girq->num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) girq->parents = devm_kcalloc(&pdev->dev, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) sizeof(*girq->parents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (!girq->parents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) girq->parents[0] = gpio->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) girq->default_type = IRQ_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) girq->handler = handle_bad_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) girq->init_valid_mask = aspeed_init_irq_valid_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) gpio->offset_timer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) devm_kzalloc(&pdev->dev, gpio->chip.ngpio, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (!gpio->offset_timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) static struct platform_driver aspeed_gpio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) .of_match_table = aspeed_gpio_of_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) module_platform_driver_probe(aspeed_gpio_driver, aspeed_gpio_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) MODULE_DESCRIPTION("Aspeed GPIO Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) MODULE_LICENSE("GPL");