|
@@ -131,10 +131,8 @@ struct chv_gpio_pinrange {
|
|
|
* @ngroups: Number of groups
|
|
|
* @functions: All functions in this community
|
|
|
* @nfunctions: Number of functions
|
|
|
- * @ngpios: Number of GPIOs in this community
|
|
|
* @gpio_ranges: An array of GPIO ranges in this community
|
|
|
* @ngpio_ranges: Number of GPIO ranges
|
|
|
- * @ngpios: Total number of GPIOs in this community
|
|
|
* @nirqs: Total number of IRQs this community can generate
|
|
|
*/
|
|
|
struct chv_community {
|
|
@@ -147,7 +145,6 @@ struct chv_community {
|
|
|
size_t nfunctions;
|
|
|
const struct chv_gpio_pinrange *gpio_ranges;
|
|
|
size_t ngpio_ranges;
|
|
|
- size_t ngpios;
|
|
|
size_t nirqs;
|
|
|
acpi_adr_space_type acpi_space_id;
|
|
|
};
|
|
@@ -399,7 +396,6 @@ static const struct chv_community southwest_community = {
|
|
|
.nfunctions = ARRAY_SIZE(southwest_functions),
|
|
|
.gpio_ranges = southwest_gpio_ranges,
|
|
|
.ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges),
|
|
|
- .ngpios = ARRAY_SIZE(southwest_pins),
|
|
|
/*
|
|
|
* Southwest community can benerate GPIO interrupts only for the
|
|
|
* first 8 interrupts. The upper half (8-15) can only be used to
|
|
@@ -489,7 +485,6 @@ static const struct chv_community north_community = {
|
|
|
.npins = ARRAY_SIZE(north_pins),
|
|
|
.gpio_ranges = north_gpio_ranges,
|
|
|
.ngpio_ranges = ARRAY_SIZE(north_gpio_ranges),
|
|
|
- .ngpios = ARRAY_SIZE(north_pins),
|
|
|
/*
|
|
|
* North community can generate GPIO interrupts only for the first
|
|
|
* 8 interrupts. The upper half (8-15) can only be used to trigger
|
|
@@ -538,7 +533,6 @@ static const struct chv_community east_community = {
|
|
|
.npins = ARRAY_SIZE(east_pins),
|
|
|
.gpio_ranges = east_gpio_ranges,
|
|
|
.ngpio_ranges = ARRAY_SIZE(east_gpio_ranges),
|
|
|
- .ngpios = ARRAY_SIZE(east_pins),
|
|
|
.nirqs = 16,
|
|
|
.acpi_space_id = 0x93,
|
|
|
};
|
|
@@ -665,7 +659,6 @@ static const struct chv_community southeast_community = {
|
|
|
.nfunctions = ARRAY_SIZE(southeast_functions),
|
|
|
.gpio_ranges = southeast_gpio_ranges,
|
|
|
.ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges),
|
|
|
- .ngpios = ARRAY_SIZE(southeast_pins),
|
|
|
.nirqs = 16,
|
|
|
.acpi_space_id = 0x94,
|
|
|
};
|
|
@@ -1253,21 +1246,14 @@ static struct pinctrl_desc chv_pinctrl_desc = {
|
|
|
.owner = THIS_MODULE,
|
|
|
};
|
|
|
|
|
|
-static unsigned chv_gpio_offset_to_pin(struct chv_pinctrl *pctrl,
|
|
|
- unsigned offset)
|
|
|
-{
|
|
|
- return pctrl->community->pins[offset].number;
|
|
|
-}
|
|
|
-
|
|
|
static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|
|
{
|
|
|
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
|
|
|
- int pin = chv_gpio_offset_to_pin(pctrl, offset);
|
|
|
unsigned long flags;
|
|
|
u32 ctrl0, cfg;
|
|
|
|
|
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
|
|
- ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
|
|
+ ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
|
|
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
|
|
|
|
|
cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
|
|
@@ -1281,14 +1267,13 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|
|
static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|
|
{
|
|
|
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
|
|
|
- unsigned pin = chv_gpio_offset_to_pin(pctrl, offset);
|
|
|
unsigned long flags;
|
|
|
void __iomem *reg;
|
|
|
u32 ctrl0;
|
|
|
|
|
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
|
|
|
|
|
- reg = chv_padreg(pctrl, pin, CHV_PADCTRL0);
|
|
|
+ reg = chv_padreg(pctrl, offset, CHV_PADCTRL0);
|
|
|
ctrl0 = readl(reg);
|
|
|
|
|
|
if (value)
|
|
@@ -1304,12 +1289,11 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|
|
static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
|
|
{
|
|
|
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
|
|
|
- unsigned pin = chv_gpio_offset_to_pin(pctrl, offset);
|
|
|
u32 ctrl0, direction;
|
|
|
unsigned long flags;
|
|
|
|
|
|
raw_spin_lock_irqsave(&chv_lock, flags);
|
|
|
- ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0));
|
|
|
+ ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0));
|
|
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
|
|
|
|
|
direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
|
|
@@ -1345,7 +1329,7 @@ static void chv_gpio_irq_ack(struct irq_data *d)
|
|
|
{
|
|
|
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
|
|
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
|
|
|
- int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d));
|
|
|
+ int pin = irqd_to_hwirq(d);
|
|
|
u32 intr_line;
|
|
|
|
|
|
raw_spin_lock(&chv_lock);
|
|
@@ -1362,7 +1346,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
|
|
|
{
|
|
|
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
|
|
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
|
|
|
- int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d));
|
|
|
+ int pin = irqd_to_hwirq(d);
|
|
|
u32 value, intr_line;
|
|
|
unsigned long flags;
|
|
|
|
|
@@ -1407,8 +1391,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
|
|
|
if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) {
|
|
|
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
|
|
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
|
|
|
- unsigned offset = irqd_to_hwirq(d);
|
|
|
- int pin = chv_gpio_offset_to_pin(pctrl, offset);
|
|
|
+ unsigned pin = irqd_to_hwirq(d);
|
|
|
irq_flow_handler_t handler;
|
|
|
unsigned long flags;
|
|
|
u32 intsel, value;
|
|
@@ -1426,7 +1409,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
|
|
|
|
|
|
if (!pctrl->intr_lines[intsel]) {
|
|
|
irq_set_handler_locked(d, handler);
|
|
|
- pctrl->intr_lines[intsel] = offset;
|
|
|
+ pctrl->intr_lines[intsel] = pin;
|
|
|
}
|
|
|
raw_spin_unlock_irqrestore(&chv_lock, flags);
|
|
|
}
|
|
@@ -1439,8 +1422,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
|
|
|
{
|
|
|
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
|
|
struct chv_pinctrl *pctrl = gpiochip_get_data(gc);
|
|
|
- unsigned offset = irqd_to_hwirq(d);
|
|
|
- int pin = chv_gpio_offset_to_pin(pctrl, offset);
|
|
|
+ unsigned pin = irqd_to_hwirq(d);
|
|
|
unsigned long flags;
|
|
|
u32 value;
|
|
|
|
|
@@ -1486,7 +1468,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type)
|
|
|
value &= CHV_PADCTRL0_INTSEL_MASK;
|
|
|
value >>= CHV_PADCTRL0_INTSEL_SHIFT;
|
|
|
|
|
|
- pctrl->intr_lines[value] = offset;
|
|
|
+ pctrl->intr_lines[value] = pin;
|
|
|
|
|
|
if (type & IRQ_TYPE_EDGE_BOTH)
|
|
|
irq_set_handler_locked(d, handle_edge_irq);
|
|
@@ -1576,12 +1558,12 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
|
|
|
const struct chv_gpio_pinrange *range;
|
|
|
struct gpio_chip *chip = &pctrl->chip;
|
|
|
bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
|
|
|
- int ret, i, offset;
|
|
|
- int irq_base;
|
|
|
+ const struct chv_community *community = pctrl->community;
|
|
|
+ int ret, i, irq_base;
|
|
|
|
|
|
*chip = chv_gpio_chip;
|
|
|
|
|
|
- chip->ngpio = pctrl->community->ngpios;
|
|
|
+ chip->ngpio = community->pins[community->npins - 1].number + 1;
|
|
|
chip->label = dev_name(pctrl->dev);
|
|
|
chip->parent = pctrl->dev;
|
|
|
chip->base = -1;
|
|
@@ -1593,30 +1575,29 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- for (i = 0, offset = 0; i < pctrl->community->ngpio_ranges; i++) {
|
|
|
- range = &pctrl->community->gpio_ranges[i];
|
|
|
- ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), offset,
|
|
|
- range->base, range->npins);
|
|
|
+ for (i = 0; i < community->ngpio_ranges; i++) {
|
|
|
+ range = &community->gpio_ranges[i];
|
|
|
+ ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev),
|
|
|
+ range->base, range->base,
|
|
|
+ range->npins);
|
|
|
if (ret) {
|
|
|
dev_err(pctrl->dev, "failed to add GPIO pin range\n");
|
|
|
return ret;
|
|
|
}
|
|
|
-
|
|
|
- offset += range->npins;
|
|
|
}
|
|
|
|
|
|
/* Do not add GPIOs that can only generate GPEs to the IRQ domain */
|
|
|
- for (i = 0; i < pctrl->community->npins; i++) {
|
|
|
+ for (i = 0; i < community->npins; i++) {
|
|
|
const struct pinctrl_pin_desc *desc;
|
|
|
u32 intsel;
|
|
|
|
|
|
- desc = &pctrl->community->pins[i];
|
|
|
+ desc = &community->pins[i];
|
|
|
|
|
|
intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
|
|
|
intsel &= CHV_PADCTRL0_INTSEL_MASK;
|
|
|
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
|
|
|
|
|
|
- if (need_valid_mask && intsel >= pctrl->community->nirqs)
|
|
|
+ if (need_valid_mask && intsel >= community->nirqs)
|
|
|
clear_bit(i, chip->irq.valid_mask);
|
|
|
}
|
|
|
|