svn commit: r352309 - in stable/12/sys: arm/mv dev/extres/syscon dev/fdt
Emmanuel Vadot
manu at FreeBSD.org
Fri Sep 13 21:20:25 UTC 2019
Author: manu
Date: Fri Sep 13 21:20:24 2019
New Revision: 352309
URL: https://svnweb.freebsd.org/changeset/base/352309
Log:
MFC r351184, r351189, r351217
r351184:
Add method for getting of syscon handle from parent device.
If simple multifuction device also provides syscon interface, its
childern should be able to consume it. Due to this:
- declare coresponding method in syscon interface
- implement it in simple multifunction device driver
r351189:
Fix bug introduced by r351184.
We should check the returned handle, not the pointer to it.
Noticed by: ian
X-MFC with: r351184
r351217:
arm64: a37x0_gpio: Use syscon instead of MMIO region
The fdt node for this driver is a simple-mfd and syscon compatible one
meaning that simplemfd will be the driver attached for it. The gpio driver
is attached to the 'gpio' subnode so use syscon_get_handle_default to
obtain the handle of the syscon from the parent device and use this
to read/write to the memory region.
Modified:
stable/12/sys/arm/mv/a37x0_gpio.c
stable/12/sys/dev/extres/syscon/syscon.c
stable/12/sys/dev/extres/syscon/syscon_if.m
stable/12/sys/dev/fdt/simple_mfd.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/arm/mv/a37x0_gpio.c
==============================================================================
--- stable/12/sys/arm/mv/a37x0_gpio.c Fri Sep 13 21:15:01 2019 (r352308)
+++ stable/12/sys/arm/mv/a37x0_gpio.c Fri Sep 13 21:20:24 2019 (r352309)
@@ -46,21 +46,14 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus_subr.h>
#include "gpio_if.h"
+#include "syscon_if.h"
-static struct resource_spec a37x0_gpio_res_spec[] = {
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Pinctl / GPIO */
- { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* Interrupts control */
- { -1, 0, 0 }
-};
-
struct a37x0_gpio_softc {
- bus_space_tag_t sc_bst;
- bus_space_handle_t sc_bsh;
device_t sc_busdev;
int sc_type;
uint32_t sc_max_pins;
uint32_t sc_npins;
- struct resource *sc_mem_res[nitems(a37x0_gpio_res_spec) - 1];
+ struct syscon *syscon;
};
/* Memory regions. */
@@ -72,9 +65,9 @@ struct a37x0_gpio_softc {
#define A37X0_SB_GPIO 2
#define A37X0_GPIO_WRITE(_sc, _off, _val) \
- bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off), (_val))
+ SYSCON_WRITE_4((_sc)->syscon, (_off), (_val))
#define A37X0_GPIO_READ(_sc, _off) \
- bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off))
+ SYSCON_READ_4((_sc)->syscon, (_off))
#define A37X0_GPIO_BIT(_p) (1U << ((_p) % 32))
#define A37X0_GPIO_OUT_EN(_p) (0x0 + ((_p) / 32) * 4)
@@ -280,6 +273,12 @@ a37x0_gpio_attach(device_t dev)
sc = device_get_softc(dev);
+ err = syscon_get_handle_default(dev, &sc->syscon);
+ if (err != 0) {
+ device_printf(dev, "Cannot get syscon handle from parent\n");
+ return (ENXIO);
+ }
+
/* Read and verify the "gpio-ranges" property. */
ncells = OF_getencprop_alloc(ofw_bus_get_node(dev), "gpio-ranges",
(void **)&ranges);
@@ -295,14 +294,6 @@ a37x0_gpio_attach(device_t dev)
/* Check the number of pins in the DTS vs HW capabilities. */
if (sc->sc_npins > sc->sc_max_pins)
return (ENXIO);
-
- err = bus_alloc_resources(dev, a37x0_gpio_res_spec, sc->sc_mem_res);
- if (err != 0) {
- device_printf(dev, "cannot allocate memory window\n");
- return (ENXIO);
- }
- sc->sc_bst = rman_get_bustag(sc->sc_mem_res[A37X0_GPIO]);
- sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res[A37X0_GPIO]);
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL)
Modified: stable/12/sys/dev/extres/syscon/syscon.c
==============================================================================
--- stable/12/sys/dev/extres/syscon/syscon.c Fri Sep 13 21:15:01 2019 (r352308)
+++ stable/12/sys/dev/extres/syscon/syscon.c Fri Sep 13 21:20:24 2019 (r352309)
@@ -254,3 +254,14 @@ syscon_get_by_ofw_property(device_t cdev, phandle_t cn
return (0);
}
#endif
+
+int
+syscon_get_handle_default(device_t dev, struct syscon **syscon)
+{
+ device_t parent;
+
+ parent = device_get_parent(dev);
+ if (parent == NULL)
+ return (ENODEV);
+ return (SYSCON_GET_HANDLE(parent, syscon));
+}
Modified: stable/12/sys/dev/extres/syscon/syscon_if.m
==============================================================================
--- stable/12/sys/dev/extres/syscon/syscon_if.m Fri Sep 13 21:15:01 2019 (r352308)
+++ stable/12/sys/dev/extres/syscon/syscon_if.m Fri Sep 13 21:20:24 2019 (r352309)
@@ -32,6 +32,7 @@ INTERFACE syscon;
HEADER {
struct syscon;
+ int syscon_get_handle_default(device_t dev, struct syscon **syscon);
}
METHOD int init {
@@ -62,3 +63,11 @@ METHOD int modify_4 {
uint32_t clear_bits;
uint32_t set_bits;
};
+
+/**
+ * Get syscon handle from parent driver
+ */
+METHOD int get_handle {
+ device_t dev;
+ struct syscon **syscon;
+} DEFAULT syscon_get_handle_default;
Modified: stable/12/sys/dev/fdt/simple_mfd.c
==============================================================================
--- stable/12/sys/dev/fdt/simple_mfd.c Fri Sep 13 21:15:01 2019 (r352308)
+++ stable/12/sys/dev/fdt/simple_mfd.c Fri Sep 13 21:20:24 2019 (r352309)
@@ -49,14 +49,16 @@ __FBSDID("$FreeBSD$");
device_t simple_mfd_add_device(device_t dev, phandle_t node, u_int order,
const char *name, int unit, struct simplebus_devinfo *di);
-struct simplebus_devinfo *simple_mfd_setup_dinfo(device_t dev, phandle_t node, struct simplebus_devinfo *di);
+struct simplebus_devinfo *simple_mfd_setup_dinfo(device_t dev, phandle_t node,
+ struct simplebus_devinfo *di);
#include "syscon_if.h"
#include <dev/extres/syscon/syscon.h>
MALLOC_DECLARE(M_SYSCON);
-static uint32_t simple_mfd_syscon_read_4(struct syscon *syscon, bus_size_t offset);
+static uint32_t simple_mfd_syscon_read_4(struct syscon *syscon,
+ bus_size_t offset);
static int simple_mfd_syscon_write_4(struct syscon *syscon, bus_size_t offset,
uint32_t val);
static int simple_mfd_syscon_modify_4(struct syscon *syscon, bus_size_t offset,
@@ -125,7 +127,18 @@ simple_mfd_syscon_modify_4(struct syscon *syscon, bus_
SYSCON_UNLOCK(sc);
return (0);
}
+static int
+simple_mfd_syscon_get_handle(device_t dev, struct syscon **syscon)
+{
+ struct simple_mfd_softc *sc;
+ sc = device_get_softc(dev);
+ *syscon = sc->syscon;
+ if (*syscon == NULL)
+ return (ENODEV);
+ return (0);
+}
+
static int
simple_mfd_probe(device_t dev)
{
@@ -278,6 +291,8 @@ simple_mfd_add_device(device_t dev, phandle_t node, u_
}
static device_method_t simple_mfd_methods[] = {
+ /* syscon interface */
+ DEVMETHOD(syscon_get_handle, simple_mfd_syscon_get_handle),
/* Device interface */
DEVMETHOD(device_probe, simple_mfd_probe),
DEVMETHOD(device_attach, simple_mfd_attach),
More information about the svn-src-stable
mailing list