Skip to content

Commit 380b1e2

Browse files
committed
gpio-exar/8250-exar: Make set of exported GPIOs configurable
On the SIMATIC, IOT2040 only a single pin is exportable as GPIO, the rest is required to operate the UART. To allow modeling this case, expand the platform device data structure to specify a (consecutive) pin subset for exporting by the gpio-exar driver. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
1 parent 277036f commit 380b1e2

File tree

2 files changed

+45
-26
lines changed

2 files changed

+45
-26
lines changed

drivers/gpio/gpio-exar.c

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct exar_gpio_chip {
3131
int index;
3232
void __iomem *regs;
3333
char name[20];
34+
unsigned int first_pin;
3435
};
3536

3637
static void exar_update(struct gpio_chip *chip, unsigned int reg, int val,
@@ -51,11 +52,12 @@ static void exar_update(struct gpio_chip *chip, unsigned int reg, int val,
5152
static int exar_set_direction(struct gpio_chip *chip, int direction,
5253
unsigned int offset)
5354
{
54-
unsigned int bank = offset / 8;
55-
unsigned int addr;
55+
struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
56+
unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
57+
EXAR_OFFSET_MPIOSEL_HI : EXAR_OFFSET_MPIOSEL_LO;
58+
unsigned int bit = (offset + exar_gpio->first_pin) % 8;
5659

57-
addr = bank ? EXAR_OFFSET_MPIOSEL_HI : EXAR_OFFSET_MPIOSEL_LO;
58-
exar_update(chip, addr, direction, offset % 8);
60+
exar_update(chip, addr, direction, bit);
5961
return 0;
6062
}
6163

@@ -73,36 +75,33 @@ static int exar_get(struct gpio_chip *chip, unsigned int reg)
7375

7476
static int exar_get_direction(struct gpio_chip *chip, unsigned int offset)
7577
{
76-
unsigned int bank = offset / 8;
77-
unsigned int addr;
78-
int val;
79-
80-
addr = bank ? EXAR_OFFSET_MPIOSEL_HI : EXAR_OFFSET_MPIOSEL_LO;
81-
val = exar_get(chip, addr) & BIT(offset % 8);
78+
struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
79+
unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
80+
EXAR_OFFSET_MPIOSEL_HI : EXAR_OFFSET_MPIOSEL_LO;
81+
unsigned int bit = (offset + exar_gpio->first_pin) % 8;
8282

83-
return !!val;
83+
return !!(exar_get(chip, addr) & BIT(bit));
8484
}
8585

8686
static int exar_get_value(struct gpio_chip *chip, unsigned int offset)
8787
{
88-
unsigned int bank = offset / 8;
89-
unsigned int addr;
90-
int val;
91-
92-
addr = bank ? EXAR_OFFSET_MPIOLVL_HI : EXAR_OFFSET_MPIOLVL_LO;
93-
val = exar_get(chip, addr) & BIT(offset % 8);
88+
struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
89+
unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
90+
EXAR_OFFSET_MPIOLVL_HI : EXAR_OFFSET_MPIOLVL_LO;
91+
unsigned int bit = (offset + exar_gpio->first_pin) % 8;
9492

95-
return !!val;
93+
return !!(exar_get(chip, addr) & BIT(bit));
9694
}
9795

9896
static void exar_set_value(struct gpio_chip *chip, unsigned int offset,
9997
int value)
10098
{
101-
unsigned int bank = offset / 8;
102-
unsigned int addr;
99+
struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
100+
unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
101+
EXAR_OFFSET_MPIOLVL_HI : EXAR_OFFSET_MPIOLVL_LO;
102+
unsigned int bit = (offset + exar_gpio->first_pin) % 8;
103103

104-
addr = bank ? EXAR_OFFSET_MPIOLVL_HI : EXAR_OFFSET_MPIOLVL_LO;
105-
exar_update(chip, addr, value, offset % 8);
104+
exar_update(chip, addr, value, bit);
106105
}
107106

108107
static int exar_direction_output(struct gpio_chip *chip, unsigned int offset,
@@ -121,6 +120,7 @@ static int gpio_exar_probe(struct platform_device *pdev)
121120
{
122121
struct pci_dev *pcidev = to_pci_dev(pdev->dev.parent);
123122
struct exar_gpio_chip *exar_gpio;
123+
u32 first_pin, ngpios;
124124
void __iomem *p;
125125
int index, ret;
126126

@@ -132,6 +132,15 @@ static int gpio_exar_probe(struct platform_device *pdev)
132132
if (!p)
133133
return -ENOMEM;
134134

135+
ret = device_property_read_u32(&pdev->dev, "linux,first-pin",
136+
&first_pin);
137+
if (ret)
138+
return ret;
139+
140+
ret = device_property_read_u32(&pdev->dev, "ngpios", &ngpios);
141+
if (ret)
142+
return ret;
143+
135144
exar_gpio = devm_kzalloc(&pdev->dev, sizeof(*exar_gpio), GFP_KERNEL);
136145
if (!exar_gpio)
137146
return -ENOMEM;
@@ -149,9 +158,10 @@ static int gpio_exar_probe(struct platform_device *pdev)
149158
exar_gpio->gpio_chip.get = exar_get_value;
150159
exar_gpio->gpio_chip.set = exar_set_value;
151160
exar_gpio->gpio_chip.base = -1;
152-
exar_gpio->gpio_chip.ngpio = 16;
161+
exar_gpio->gpio_chip.ngpio = ngpios;
153162
exar_gpio->regs = p;
154163
exar_gpio->index = index;
164+
exar_gpio->first_pin = first_pin;
155165

156166
ret = devm_gpiochip_add_data(&pdev->dev,
157167
&exar_gpio->gpio_chip, exar_gpio);

drivers/tty/serial/8250/8250_exar.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/kernel.h>
1515
#include <linux/module.h>
1616
#include <linux/pci.h>
17+
#include <linux/property.h>
1718
#include <linux/serial_core.h>
1819
#include <linux/serial_reg.h>
1920
#include <linux/slab.h>
@@ -194,7 +195,8 @@ static void setup_gpio(u8 __iomem *p)
194195
}
195196

196197
static void *
197-
__xr17v35x_register_gpio(struct pci_dev *pcidev)
198+
__xr17v35x_register_gpio(struct pci_dev *pcidev,
199+
const struct property_entry *properties)
198200
{
199201
struct platform_device *pdev;
200202

@@ -205,20 +207,27 @@ __xr17v35x_register_gpio(struct pci_dev *pcidev)
205207
pdev->dev.parent = &pcidev->dev;
206208
ACPI_COMPANION_SET(&pdev->dev, ACPI_COMPANION(&pcidev->dev));
207209

208-
if (platform_device_add(pdev) < 0) {
210+
if (platform_device_add_properties(pdev, properties) < 0 ||
211+
platform_device_add(pdev) < 0) {
209212
platform_device_put(pdev);
210213
return NULL;
211214
}
212215

213216
return pdev;
214217
}
215218

219+
static const struct property_entry exar_gpio_properties[] = {
220+
PROPERTY_ENTRY_U32("linux,first-pin", 0),
221+
PROPERTY_ENTRY_U32("ngpios", 16),
222+
{ }
223+
};
224+
216225
static int xr17v35x_register_gpio(struct pci_dev *pcidev,
217226
struct uart_8250_port *port)
218227
{
219228
if (pcidev->vendor == PCI_VENDOR_ID_EXAR)
220229
port->port.private_data =
221-
__xr17v35x_register_gpio(pcidev);
230+
__xr17v35x_register_gpio(pcidev, exar_gpio_properties);
222231

223232
return 0;
224233
}

0 commit comments

Comments
 (0)