iPXE
dwgpio.c File Reference

Synopsys DesignWare GPIO driver. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/devtree.h>
#include <ipxe/fdt.h>
#include <ipxe/gpio.h>
#include "dwgpio.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int dwgpio_group_probe (struct dt_device *dt, unsigned int offset)
 Probe port group.
static void dwgpio_group_remove (struct dt_device *dt)
 Remove port group.
static void dwgpio_dump (struct dwgpio *dwgpio)
 Dump GPIO port status.
static int dwgpio_in (struct gpios *gpios, struct gpio *gpio)
 Get current GPIO input value.
static void dwgpio_out (struct gpios *gpios, struct gpio *gpio, int active)
 Set current GPIO output value.
static int dwgpio_config (struct gpios *gpios, struct gpio *gpio, unsigned int config)
 Configure GPIO pin.
static int dwgpio_probe (struct dt_device *dt, unsigned int offset)
 Probe port.
static void dwgpio_remove (struct dt_device *dt)
 Remove port.

Variables

static const char * dwgpio_group_ids []
 DesignWare GPIO port group compatible model identifiers.
struct dt_driver dwgpio_group_driver __dt_driver
 DesignWare GPIO port group devicetree driver.
static struct gpio_operations dwgpio_operations
 GPIO operations.
static const char * dwgpio_ids []
 DesignWare GPIO port compatible model identifiers.

Detailed Description

Synopsys DesignWare GPIO driver.

Definition in file dwgpio.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ dwgpio_group_probe()

int dwgpio_group_probe ( struct dt_device * dt,
unsigned int offset )
static

Probe port group.

Parameters
dtDevicetree device
offsetStarting node offset
Return values
rcReturn status code

Definition at line 54 of file dwgpio.c.

54 {
55 struct dwgpio_group *group;
56 int rc;
57
58 /* Allocate and initialise structure */
59 group = zalloc ( sizeof ( *group ) );
60 if ( ! group ) {
61 rc = -ENOMEM;
62 goto err_alloc;
63 }
64 dt_set_drvdata ( dt, group );
65
66 /* Map registers */
67 group->regs = dt_ioremap ( dt, offset, 0, 0 );
68 if ( ! group->regs ) {
69 rc = -ENODEV;
70 goto err_ioremap;
71 }
72
73 /* Probe child ports */
74 if ( ( rc = dt_probe_children ( dt, offset ) ) != 0 )
75 goto err_children;
76
77 return 0;
78
79 dt_remove_children ( dt );
80 err_children:
81 iounmap ( group->regs );
82 err_ioremap:
83 free ( group );
84 err_alloc:
85 return rc;
86}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
uint16_t offset
Offset to command line.
Definition bzimage.h:3
void * dt_ioremap(struct dt_device *dt, unsigned int offset, unsigned int index, size_t len)
Map devicetree range.
Definition devtree.c:52
int dt_probe_children(struct dt_device *parent, unsigned int offset)
Probe devicetree children.
Definition devtree.c:264
void dt_remove_children(struct dt_device *parent)
Remove devicetree children.
Definition devtree.c:310
static void dt_set_drvdata(struct dt_device *dt, void *priv)
Set devicetree driver-private data.
Definition devtree.h:72
uint16_t group
Type of event.
Definition ena.h:1
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENODEV
No such device.
Definition errno.h:510
void iounmap(volatile const void *io_addr)
Unmap I/O address.
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
A DesignWare GPIO port group.
Definition dwgpio.h:55

References dt_ioremap(), dt_probe_children(), dt_remove_children(), dt_set_drvdata(), ENODEV, ENOMEM, free, group, iounmap(), offset, rc, and zalloc().

◆ dwgpio_group_remove()

void dwgpio_group_remove ( struct dt_device * dt)
static

Remove port group.

Parameters
dtDevicetree device

Definition at line 93 of file dwgpio.c.

93 {
94 struct dwgpio_group *group = dt_get_drvdata ( dt );
95
96 /* Remove child ports */
97 dt_remove_children ( dt );
98
99 /* Unmap registers */
100 iounmap ( group->regs );
101
102 /* Free device */
103 free ( group );
104}
static void * dt_get_drvdata(struct dt_device *dt)
Get devicetree driver-private data.
Definition devtree.h:82

References dt_get_drvdata(), dt_remove_children(), free, group, and iounmap().

◆ dwgpio_dump()

void dwgpio_dump ( struct dwgpio * dwgpio)
inlinestatic

Dump GPIO port status.

Parameters
dwgpioDesignWare GPIO port

Definition at line 133 of file dwgpio.c.

133 {
134
135 DBGC2 ( dwgpio, "DWGPIO %s dr %#08x ddr %#08x ctl %#08x\n",
139}
#define DWGPIO_SWPORT_DR
Data register.
Definition dwgpio.h:30
#define DWGPIO_SWPORT_DDR
Data direction register.
Definition dwgpio.h:37
#define DWGPIO_SWPORT_CTL
Control register.
Definition dwgpio.h:45
#define DBGC2(...)
Definition compiler.h:522
A DesignWare GPIO port.
Definition dwgpio.h:61
const char * name
Device name.
Definition dwgpio.h:63
void * swport
Software port registers.
Definition dwgpio.h:67
#define readl
Definition w89c840.c:157

References DBGC2, DWGPIO_SWPORT_CTL, DWGPIO_SWPORT_DDR, DWGPIO_SWPORT_DR, dwgpio::name, readl, and dwgpio::swport.

Referenced by dwgpio_config(), dwgpio_out(), and dwgpio_probe().

◆ dwgpio_in()

int dwgpio_in ( struct gpios * gpios,
struct gpio * gpio )
static

Get current GPIO input value.

Parameters
gpiosGPIO controller
gpioGPIO pin
Return values
activePin is in the active state

Definition at line 148 of file dwgpio.c.

148 {
149 struct dwgpio *dwgpio = gpios->priv;
151
152 /* Read external port status */
153 ext = readl ( dwgpio->ext );
154 return ( ( ( ext >> gpio->index ) ^ gpio->config ) & 1 );
155}
unsigned int uint32_t
Definition stdint.h:12
uint16_t ext
Extended status.
Definition ena.h:9
void * ext
External port register.
Definition dwgpio.h:69
A GPIO pin.
Definition gpio.h:18
unsigned int config
Configuration.
Definition gpio.h:24
unsigned int index
Pin index.
Definition gpio.h:22
A GPIO controller.
Definition gpio.h:37
void * priv
Driver-private data.
Definition gpio.h:53

References gpio::config, dwgpio::ext, ext, gpio::index, gpios::priv, and readl.

◆ dwgpio_out()

void dwgpio_out ( struct gpios * gpios,
struct gpio * gpio,
int active )
static

Set current GPIO output value.

Parameters
gpiosGPIO controller
gpioGPIO pin
activeSet pin to active state

Definition at line 164 of file dwgpio.c.

164 {
165 struct dwgpio *dwgpio = gpios->priv;
166 uint32_t mask = ( 1UL << gpio->index );
167 uint32_t dr;
168
169 /* Update data register */
171 dr &= ~mask;
172 if ( ( ( !! active ) ^ gpio->config ) & 1 )
173 dr |= mask;
176}
static void dwgpio_dump(struct dwgpio *dwgpio)
Dump GPIO port status.
Definition dwgpio.c:133
static unsigned long dr[NUM_HWBP]
Hardware breakpoint addresses (debug registers 0-3)
Definition gdbmach.c:73
#define writel
Definition w89c840.c:160

References gpio::config, dr, dwgpio_dump(), DWGPIO_SWPORT_DR, gpio::index, gpios::priv, readl, dwgpio::swport, and writel.

◆ dwgpio_config()

int dwgpio_config ( struct gpios * gpios,
struct gpio * gpio,
unsigned int config )
static

Configure GPIO pin.

Parameters
gpiosGPIO controller
gpioGPIO pin
configConfiguration
Return values
rcReturn status code

Definition at line 186 of file dwgpio.c.

187 {
188 struct dwgpio *dwgpio = gpios->priv;
189 uint32_t mask = ( 1UL << gpio->index );
192
193 /* Update data direction and control registers */
196 ctl &= ~mask;
197 ddr &= ~mask;
198 if ( config & GPIO_CFG_OUTPUT )
199 ddr |= mask;
203
204 return 0;
205}
#define GPIO_CFG_OUTPUT
GPIO is an output.
Definition gpio.h:34
uint32_t ctl
Original control register value.
Definition dwgpio.h:76
uint32_t ddr
Original data direction register value.
Definition dwgpio.h:74

References dwgpio::ctl, dwgpio::ddr, dwgpio_dump(), DWGPIO_SWPORT_CTL, DWGPIO_SWPORT_DDR, GPIO_CFG_OUTPUT, gpio::index, gpios::priv, readl, dwgpio::swport, and writel.

◆ dwgpio_probe()

int dwgpio_probe ( struct dt_device * dt,
unsigned int offset )
static

Probe port.

Parameters
dtDevicetree device
offsetStarting node offset
Return values
rcReturn status code

Definition at line 221 of file dwgpio.c.

221 {
222 struct dt_device *parent;
223 struct dwgpio_group *group;
224 struct dwgpio *dwgpio;
225 struct gpios *gpios;
228 int rc;
229
230 /* Get number of GPIOs */
231 if ( ( rc = fdt_u32 ( &sysfdt, offset, "nr-gpios-snps",
232 &count ) ) != 0 ) {
233 goto err_count;
234 }
236
237 /* Allocate and initialise device */
238 gpios = alloc_gpios ( count, sizeof ( *dwgpio ) );
239 if ( ! gpios ) {
240 rc = -ENOMEM;
241 goto err_alloc;
242 }
243 dt_set_drvdata ( dt, gpios );
244 gpios->dev = &dt->dev;
246 dwgpio = gpios->priv;
247 dwgpio->name = dt->name;
248
249 /* Identify group */
250 parent = dt_parent ( dt );
251 if ( parent->driver != &dwgpio_group_driver ) {
252 DBGC ( dwgpio, "DWGPIO %s has invalid parent %s\n",
253 dwgpio->name, parent->name );
254 rc = -EINVAL;
255 goto err_parent;
256 }
257 group = dt_get_drvdata ( parent );
258
259 /* Identify port */
260 if ( ( rc = fdt_reg ( &sysfdt, offset, &port ) ) != 0 ) {
261 DBGC ( dwgpio, "DWGPIO %s could not get port number: %s\n",
262 dwgpio->name, strerror ( rc ) );
263 goto err_port;
264 }
265 dwgpio->port = port;
266 DBGC ( dwgpio, "DWGPIO %s is %s port %d (%d GPIOs)\n",
267 dwgpio->name, parent->name, dwgpio->port, gpios->count );
268
269 /* Map registers */
270 dwgpio->swport = ( group->regs + DWGPIO_SWPORT ( port ) );
271 dwgpio->ext = ( group->regs + DWGPIO_EXT_PORT ( port ) );
273
274 /* Record original register values */
278
279 /* Register GPIO controller */
280 if ( ( rc = gpios_register ( gpios ) ) != 0 ) {
281 DBGC ( dwgpio, "DWGPIO %s could not register: %s\n",
282 dwgpio->name, strerror ( rc ) );
283 goto err_register;
284 }
285
286 return 0;
287
289 err_register:
290 err_port:
291 err_parent:
293 gpios_put ( gpios );
294 err_alloc:
295 err_count:
296 return rc;
297}
u8 port
Port number.
Definition CIB_PRM.h:3
unsigned long long uint64_t
Definition stdint.h:13
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
static struct dt_device * dt_parent(struct dt_device *dt)
Get devicetree parent device.
Definition devtree.h:92
static struct gpio_operations dwgpio_operations
GPIO operations.
Definition dwgpio.c:208
#define DWGPIO_MAX_COUNT
Maximum number of GPIOs per port.
Definition dwgpio.h:13
#define DWGPIO_EXT_PORT(x)
External port.
Definition dwgpio.h:52
#define DWGPIO_SWPORT(x)
Software port.
Definition dwgpio.h:19
int fdt_reg(struct fdt *fdt, unsigned int offset, uint64_t *region)
Get unsized single-entry region address.
Definition fdt.c:844
int fdt_u32(struct fdt *fdt, unsigned int offset, const char *name, uint32_t *value)
Get 32-bit integer property.
Definition fdt.c:664
struct fdt sysfdt
The system flattened device tree (if present)
Definition fdt.c:45
int gpios_register(struct gpios *gpios)
Register GPIO controller.
Definition gpio.c:78
struct gpios * alloc_gpios(unsigned int count, size_t priv_len)
Allocate GPIO controller.
Definition gpio.c:46
void gpios_unregister(struct gpios *gpios)
Unregister GPIO controller.
Definition gpio.c:94
static void gpios_nullify(struct gpios *gpios)
Stop using a GPIO controller.
Definition gpio.h:152
static void gpios_init(struct gpios *gpios, struct gpio_operations *op)
Initialise a GPIO controller.
Definition gpio.h:139
static void gpios_put(struct gpios *gpios)
Drop reference to GPIO controller.
Definition gpio.h:106
#define DBGC(...)
Definition compiler.h:505
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define EINVAL
Invalid argument.
Definition errno.h:429
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A devicetree device.
Definition devtree.h:17
struct dt_driver * driver
Driver for this device.
Definition devtree.h:25
struct device dev
Generic device.
Definition devtree.h:21
const char * name
Device name.
Definition devtree.h:19
unsigned int port
Port index.
Definition dwgpio.h:65
uint32_t dr
Original data register value.
Definition dwgpio.h:72
unsigned int count
Number of GPIOs.
Definition gpio.h:45
struct device * dev
Generic device.
Definition gpio.h:43

References alloc_gpios(), assert, count, gpios::count, dwgpio::ctl, DBGC, dwgpio::ddr, dt_device::dev, gpios::dev, dwgpio::dr, dt_device::driver, dt_get_drvdata(), dt_parent(), dt_set_drvdata(), dwgpio_dump(), DWGPIO_EXT_PORT, DWGPIO_MAX_COUNT, dwgpio_operations, DWGPIO_SWPORT, DWGPIO_SWPORT_CTL, DWGPIO_SWPORT_DDR, DWGPIO_SWPORT_DR, EINVAL, ENOMEM, dwgpio::ext, fdt_reg(), fdt_u32(), gpios_init(), gpios_nullify(), gpios_put(), gpios_register(), gpios_unregister(), group, dt_device::name, dwgpio::name, offset, dwgpio::port, port, gpios::priv, rc, readl, strerror(), dwgpio::swport, and sysfdt.

◆ dwgpio_remove()

void dwgpio_remove ( struct dt_device * dt)
static

Remove port.

Parameters
dtDevicetree device

Definition at line 304 of file dwgpio.c.

304 {
305 struct gpios *gpios = dt_get_drvdata ( dt );
306 struct dwgpio *dwgpio = gpios->priv;
307
308 /* Unregister GPIO controller */
310
311 /* Restore original register values */
315
316 /* Free GPIO device */
318 gpios_put ( gpios );
319}

References dwgpio::ctl, dwgpio::ddr, dwgpio::dr, dt_get_drvdata(), DWGPIO_SWPORT_CTL, DWGPIO_SWPORT_DDR, DWGPIO_SWPORT_DR, gpios_nullify(), gpios_put(), gpios_unregister(), gpios::priv, dwgpio::swport, and writel.

Variable Documentation

◆ dwgpio_group_ids

const char* dwgpio_group_ids[]
static
Initial value:
= {
DT_ID ( "snps,dw-apb-gpio", "DesignWare GPIO" ),
}
#define DT_ID(_name, _desc)
Definition devtree.h:31

DesignWare GPIO port group compatible model identifiers.

Definition at line 107 of file dwgpio.c.

107 {
108 DT_ID ( "snps,dw-apb-gpio", "DesignWare GPIO" ),
109};

◆ __dt_driver

struct dt_driver dwgpio_driver __dt_driver
Initial value:
= {
.name = "dwgpio-group",
.id_count = ( sizeof ( dwgpio_group_ids ) /
sizeof ( dwgpio_group_ids[0] ) ),
}
static void dwgpio_group_remove(struct dt_device *dt)
Remove port group.
Definition dwgpio.c:93
static int dwgpio_group_probe(struct dt_device *dt, unsigned int offset)
Probe port group.
Definition dwgpio.c:54
static const char * dwgpio_group_ids[]
DesignWare GPIO port group compatible model identifiers.
Definition dwgpio.c:107
static struct xen_remove_from_physmap * remove
Definition xenmem.h:40

DesignWare GPIO port group devicetree driver.

DesignWare GPIO port devicetree driver.

Definition at line 112 of file dwgpio.c.

112 {
113 .name = "dwgpio-group",
114 .ids = dwgpio_group_ids,
115 .id_count = ( sizeof ( dwgpio_group_ids ) /
116 sizeof ( dwgpio_group_ids[0] ) ),
117 .probe = dwgpio_group_probe,
119};

◆ dwgpio_operations

struct gpio_operations dwgpio_operations
static
Initial value:
= {
.in = dwgpio_in,
.out = dwgpio_out,
.config = dwgpio_config,
}
static int dwgpio_in(struct gpios *gpios, struct gpio *gpio)
Get current GPIO input value.
Definition dwgpio.c:148
static int dwgpio_config(struct gpios *gpios, struct gpio *gpio, unsigned int config)
Configure GPIO pin.
Definition dwgpio.c:186
static void dwgpio_out(struct gpios *gpios, struct gpio *gpio, int active)
Set current GPIO output value.
Definition dwgpio.c:164

GPIO operations.

Definition at line 208 of file dwgpio.c.

208 {
209 .in = dwgpio_in,
210 .out = dwgpio_out,
211 .config = dwgpio_config,
212};

Referenced by dwgpio_probe().

◆ dwgpio_ids

const char* dwgpio_ids[]
static
Initial value:
= {
DT_ID ( "snps,dw-apb-gpio-port", "DesignWare GPIO port" ),
}

DesignWare GPIO port compatible model identifiers.

Definition at line 322 of file dwgpio.c.

322 {
323 DT_ID ( "snps,dw-apb-gpio-port", "DesignWare GPIO port" ),
324};