HardenedBSD/src 135f00a — include string.h, share/man/man9 VFS_QUOTACTL.9 iflibtxrx.9
Merge branch 'freebsd/current/master' into hardened/current/master * freebsd/current/master: (23 commits) VFS_QUOTACTL: Remove needless casts of arg net tests: Re-enable most if_clone tests Fix f_pkt_into_t typo. Use __containerof() instead of home-rolled versions. Describe the commit message template our git hook script produces Use a template assembly file for firmware object files. Cleanups to *ERR* compat shims. chmod +x the git commit message prep hook Add initial version of git commit message preparation hook Fix a race in tty_signal_sessleader() with unlocked read of s_leader. Update the unbound version number from r368478. fd: reimplement close_range to avoid spurious relocking audit: rework AUDIT_SYSCLOSE fd: refactor closefp in preparation for close_range rework lualoader: fix lua-lint run lualoader: cli: provide a show-module-options loader command [ng_socket] Don't take the SOCKBUF_LOCK() twice in the RX data path. Add IRQ resource to SPIBUS arm: Remove samsung exnynos port Change POSIX compliance level for visibility of strerror_l(3). ...
@@ -140,7 +140,7 @@ int timingsafe_bcmp( | |||
int timingsafe_memcm | int timingsafe_memcm | ||
#endif /* __BSD_VISIBLE */ | #endif /* __BSD_VISIBLE */ | ||
-#if __POSIX_VISIBLE >= | +#if __POSIX_VISIBLE >= 200112 || defined(_XLOCALE_H_) | ||
#include <xlocale/_string.h> | #include <xlocale/_string.h> | ||
#endif | #endif | ||
@@ -28,7 +28,7 @@ | |||
.\" | .\" | ||
.\" $FreeBSD$ | .\" $FreeBSD$ | ||
.\" | .\" | ||
-.Dd May 23, 2009 | +.Dd December 17, 2020 | ||
.Dt VFS_QUOTACTL 9 | .Dt VFS_QUOTACTL 9 | ||
.Os | .Os | ||
.Sh NAME | .Sh NAME | ||
@@ -39,7 +39,7 @@ | |||
.In sys/mount.h | .In sys/mount.h | ||
.In sys/vnode.h | .In sys/vnode.h | ||
.Ft int | .Ft int | ||
-.Fn VFS_QUOTACTL "struct mount *mp" "int cmds" "uid_t uid" | +.Fn VFS_QUOTACTL "struct mount *mp" "int cmds" "uid_t uid" "void *arg" | ||
.Sh DESCRIPTION | .Sh DESCRIPTION | ||
Implement file system quotas. | Implement file system quotas. | ||
See | See |
@@ -1,5 +1,5 @@ | |||
.\" $FreeBSD$ | .\" $FreeBSD$ | ||
-.Dd April 16, 2019 | +.Dd December 17, 2020 | ||
.Dt IFLIBTXTX 9 | .Dt IFLIBTXTX 9 | ||
.Os | .Os | ||
.Sh NAME | .Sh NAME | ||
@@ -11,7 +11,7 @@ | |||
.Ft int | .Ft int | ||
.Fo isc_txd_encap | .Fo isc_txd_encap | ||
.Fa "void *sc" | .Fa "void *sc" | ||
-.Fa | +.Fa "if_pkt_info_t pi" | ||
.Fc | .Fc | ||
.Ft void | .Ft void | ||
.Fo isc_txd_flush | .Fo isc_txd_flush |
@@ -174,9 +174,7 @@ out: | |||
#endif /* __i386__ || __amd64__ */ | #endif /* __i386__ || __amd64__ */ | ||
#ifndef EFI_STAGING_SIZE | #ifndef EFI_STAGING_SIZE | ||
-#if defined( | +#if defined(__arm__) | ||
-#define EFI_STAGING_SIZE | |||
-#elif defined(__arm__) | |||
#define EFI_STAGING_SIZE | #define EFI_STAGING_SIZE | ||
#else | #else | ||
#define EFI_STAGING_SIZE | #define EFI_STAGING_SIZE |
@@ -32,6 +32,18 @@ local core = require("core") | |||
local cli = {} | local cli = {} | ||
+if not pager then | |||
+ -- shim for the pager module that just doesn't do it. | |||
+ -- XXX Remove after 12.2 goes EoL. | |||
+ pager = { | |||
+ open = function() end, | |||
+ close = function() end, | |||
+ output = function(str) | |||
+ printc(str) | |||
+ end, | |||
+ } | |||
+end | |||
+ |
@@ -26,7 +26,7 @@ | |||
.\" | .\" | ||
.\" $FreeBSD$ | .\" $FreeBSD$ | ||
.\" | .\" | ||
-.Dd December | +.Dd December 17, 2020 | ||
.Dt CLI.LUA 8 | .Dt CLI.LUA 8 | ||
.Os | .Os | ||
.Sh NAME | .Sh NAME | ||
@@ -96,6 +96,8 @@ module provides the following default commands: | |||
.Ic disable-module | .Ic disable-module | ||
.It | .It | ||
.Ic toggle-module | .Ic toggle-module | ||
+.It | |||
+.Ic show-module-options | |||
.El | .El | ||
.Pp | .Pp | ||
For | For | ||
@@ -125,6 +127,10 @@ commands manipulate the list of modules to be loaded along with the kernel. | |||
Modules blacklisted are considered disabled by | Modules blacklisted are considered disabled by | ||
.Ic toggle-module . | .Ic toggle-module . | ||
These commands will override any such restriction as needed. | These commands will override any such restriction as needed. | ||
+The | |||
+.Ic show-module-options | |||
+command will dump the list of modules that loader has been made aware of and | |||
+any applicable options using paged output. | |||
.Ss Exported Functions | .Ss Exported Functions | ||
The following functions are exported from | The following functions are exported from | ||
.Nm : | .Nm : |
@@ -721,6 +721,13 @@ function config.isModuleE | |||
return not blacklist[modname] | return not blacklist[modname] | ||
end | end | ||
+function config.getModuleInfo() | |||
+ return { | |||
+ modules = modules, | |||
+ blacklist = getBlacklist() | |||
+ } | |||
+end | |||
+ | |||
hook.registerType("config.loaded") | hook.registerType("config.loaded") | ||
hook.registerType("config.reloaded") | hook.registerType("config.reloaded") | ||
hook.registerType("kernel.loaded") | hook.registerType("kernel.loaded") |
@@ -26,7 +26,7 @@ | |||
.\" | .\" | ||
.\" $FreeBSD$ | .\" $FreeBSD$ | ||
.\" | .\" | ||
-.Dd December | +.Dd December 17, 2020 | ||
.Dt CONFIG.LUA 8 | .Dt CONFIG.LUA 8 | ||
.Os | .Os | ||
.Sh NAME | .Sh NAME | ||
@@ -203,6 +203,15 @@ will be loaded during | |||
.Fn config.loadelf . | .Fn config.loadelf . | ||
It checks both that the module is marked for loading and that it is either | It checks both that the module is marked for loading and that it is either | ||
forced or not blacklisted. | forced or not blacklisted. | ||
+.It Fn config.getModuleInfo | |||
+Returns a table with | |||
+.Dq modules | |||
+and | |||
+.Dq blacklist | |||
+tables describing the modules that the config module has been made aware of via | |||
+.Xr loader.conf 5 | |||
+as well as a representation of | |||
+.Ar module_blacklist | |||
.El | .El | ||
.Ss Defined Hooks | .Ss Defined Hooks | ||
The following hooks are defined in | The following hooks are defined in |
@@ -1,301 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPREC OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNEC FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINEC INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Samsung Chromebook Embedded Controller | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
-#include <sys/gpio.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include <dev/iicbus/iiconf.h> | |||
- | |||
-#include "iicbus_if.h" | |||
-#include "gpio_if.h" | |||
- | |||
-#include <arm/samsung/exynos/chrome_ec.h> | |||
- | |||
-struct ec_softc { | |||
- device_t dev; | |||
- int have_arbitrator; | |||
- pcell_t our_gpio; | |||
- pcell_t ec_gpio; | |||
-}; | |||
- | |||
-struct ec_softc *ec_sc; | |||
- | |||
-/* | |||
- * bus_claim, bus_release | |||
- * both functions used for bus arbitration | |||
- * in multi-master mode | |||
- */ | |||
- | |||
-static int | |||
-bus_claim(struct ec_softc *sc) | |||
-{ | |||
- device_t gpio_dev; | |||
- int status; | |||
- | |||
- if (sc->our_gpio == 0 || sc->ec_gpio == 0) { | |||
- device_printf(sc->dev, "i2c arbitrator is not configured\n"); | |||
- return (1); | |||
- } | |||
- | |||
- gpio_dev = devclass_get_dev | |||
- if (gpio_dev == NULL) { | |||
- device_printf(sc->dev, "cant find gpio_dev\n"); | |||
- return (1); | |||
- } | |||
- | |||
- /* Say we want the bus */ | |||
- GPIO_PIN_SET(gpio_dev, sc->our_gpio, GPIO_PIN_LOW); | |||
- | |||
- /* TODO: insert a delay to allow EC to react. */ | |||
- | |||
- /* Check EC decision */ | |||
- GPIO_PIN_GET(gpio_dev, sc->ec_gpio, &status); | |||
- | |||
- if (status == 1) { | |||
- /* Okay. We have bus */ | |||
- return (0); | |||
- } | |||
- | |||
- /* EC is master */ | |||
- return (-1); | |||
-} | |||
- | |||
-static int | |||
-bus_release(struct ec_softc *sc) | |||
-{ | |||
- device_t gpio_dev; | |||
- | |||
- if (sc->our_gpio == 0 || sc->ec_gpio == 0) { | |||
- device_printf(sc->dev, "i2c arbitrator is not configured\n"); | |||
- return (1); | |||
- } | |||
- | |||
- gpio_dev = devclass_get_dev | |||
- if (gpio_dev == NULL) { | |||
- device_printf(sc->dev, "cant find gpio_dev\n"); | |||
- return (1); | |||
- } | |||
- | |||
- GPIO_PIN_SET(gpio_dev, sc->our_gpio, GPIO_PIN_HIGH); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-ec_probe(device_t dev) | |||
-{ | |||
- | |||
- device_set_desc(dev, "Chromebook Embedded Controller"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-fill_checksum(uint8_t *data_out, int len) | |||
-{ | |||
- int res; | |||
- int i; | |||
- | |||
- res = 0; | |||
- for (i = 0; i < len; i++) { | |||
- res += data_out[i]; | |||
- } | |||
- | |||
- data_out[len] = (res & 0xff); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-int | |||
-ec_command(uint8_t cmd, uint8_t *dout, uint8_t dout_len, | |||
- uint8_t *dinp, uint8_t dinp_len) | |||
-{ | |||
- struct ec_softc *sc; | |||
- uint8_t *msg_dout; | |||
- uint8_t *msg_dinp; | |||
- int ret; | |||
- int i; | |||
- | |||
- msg_dout = malloc(dout_len + 4, M_DEVBUF, M_NOWAIT); | |||
- msg_dinp = malloc(dinp_len + 3, M_DEVBUF, M_NOWAIT); | |||
- | |||
- if (ec_sc == NULL) | |||
- return (-1); | |||
- | |||
- sc = ec_sc; | |||
- | |||
- msg_dout[0] = EC_CMD_VERSION0; | |||
- msg_dout[1] = cmd; | |||
- msg_dout[2] = dout_len; | |||
- | |||
- for (i = 0; i < dout_len; i++) { | |||
- msg_dout[i + 3] = dout[i]; | |||
- } | |||
- | |||
- fill_checksum(msg_dout, dout_len + 3); | |||
- | |||
- struct iic_msg msgs[] = { | |||
- { 0x1e, IIC_M_WR, dout_len + 4, msg_dout, }, | |||
- { 0x1e, IIC_M_RD, dinp_len + 3, msg_dinp, }, | |||
- }; | |||
- | |||
- ret = iicbus_transfer(sc->dev, msgs, 2); | |||
- if (ret != 0) { | |||
- device_printf(sc->dev, "i2c transfer returned %d\n", ret); | |||
- free(msg_dout, M_DEVBUF); | |||
- free(msg_dinp, M_DEVBUF); | |||
- return (-1); | |||
- } | |||
- | |||
- for (i = 0; i < dinp_len; i++) { | |||
- dinp[i] = msg_dinp[i + 2]; | |||
- } | |||
- | |||
- free(msg_dout, M_DEVBUF); | |||
- free(msg_dinp, M_DEVBUF); | |||
- return (0); | |||
-} | |||
- | |||
-int ec_hello(void) | |||
-{ | |||
- uint8_t data_in[4]; | |||
- uint8_t data_out[4]; | |||
- | |||
- data_in[0] = 0x40; | |||
- data_in[1] = 0x30; | |||
- data_in[2] = 0x20; | |||
- data_in[3] = 0x10; | |||
- | |||
- ec_command(EC_CMD_HELLO, data_in, 4, | |||
- data_out, 4); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static void | |||
-configure_i2c_ar | |||
-{ | |||
- phandle_t arbitrator; | |||
- | |||
- /* TODO: look for compatible entry instead of hard-coded path */ | |||
- arbitrator = OF_finddevice("/i2c-arbitrator"); | |||
- if (arbitrator != -1 && | |||
- OF_hasprop(arbitrator, "freebsd,our-gpio") && | |||
- OF_hasprop(arbitrator, "freebsd,ec-gpio")) { | |||
- sc->have_arbitrator = 1; | |||
- OF_getencprop(arbitrator, "freebsd,our-gpio", | |||
- &sc->our_gpio, sizeof(sc->our_gpio)); | |||
- OF_getencprop(arbitrator, "freebsd,ec-gpio", | |||
- &sc->ec_gpio, sizeof(sc->ec_gpio)); | |||
- } else { | |||
- sc->have_arbitrator = 0; | |||
- sc->our_gpio = 0; | |||
- sc->ec_gpio = 0; | |||
- } | |||
-} | |||
- | |||
-static int | |||
-ec_attach(device_t dev) | |||
-{ | |||
- struct ec_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- sc->dev = dev; | |||
- | |||
- ec_sc = sc; | |||
- | |||
- configure_i2c_ar | |||
- | |||
- /* | |||
- * Claim the bus. | |||
- * | |||
- * We don't know cases when EC is master, | |||
- * so hold the bus forever for us. | |||
- * | |||
- */ | |||
- | |||
- if (sc->have_arbitrator && bus_claim(sc) != 0) { | |||
- return (ENXIO); | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-ec_detach(device_t dev) | |||
-{ | |||
- struct ec_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- if (sc->have_arbitrator) { | |||
- bus_release(sc); | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static device_method_t ec_methods[] = { | |||
- DEVMETHOD(device_probe, ec_probe), | |||
- DEVMETHOD(device_attach, ec_attach), | |||
- DEVMETHOD(device_detach, ec_detach), | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t ec_driver = { | |||
- "chrome_ec", | |||
- ec_methods, | |||
- sizeof(struct ec_softc), | |||
-}; | |||
- | |||
-static devclass_t ec_devclass; | |||
- | |||
-DRIVER_MODULE(chrome_ec, iicbus, ec_driver, ec_devclass, 0, 0); | |||
-MODULE_VERSION(chrome_ec, 1); | |||
-MODULE_DEPEND(chrome_ec, iicbus, 1, 1, 1); |
@@ -1,228 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPREC OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNEC FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINEC INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Samsung Chromebook Embedded Controller (EC) | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
-#include <sys/gpio.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include <dev/spibus/spi.h> | |||
-#include <dev/spibus/spibusvar.h> | |||
- | |||
-#include "spibus_if.h" | |||
-#include "gpio_if.h" | |||
- | |||
-#include <arm/samsung/exynos/chrome_ec.h> | |||
- | |||
-struct ec_softc { | |||
- device_t dev; | |||
- device_t dev_gpio; | |||
-}; | |||
- | |||
-struct ec_softc *ec_sc; | |||
- | |||
-#define EC_SPI_CS 200 | |||
- | |||
-static int | |||
-assert_cs(struct ec_softc *sc, int enable) | |||
-{ | |||
- /* Get the GPIO device */ | |||
- sc->dev_gpio = devclass_get_dev | |||
- if (sc->dev_gpio == NULL) { | |||
- device_printf(sc->dev, "Error: failed to get the GPIO dev\n"); | |||
- return (1); | |||
- } | |||
- | |||
- GPIO_PIN_SETFLAG | |||
- | |||
- if (enable) { | |||
- GPIO_PIN_SET(sc->dev_gpio, EC_SPI_CS, GPIO_PIN_LOW); | |||
- } else { | |||
- GPIO_PIN_SET(sc->dev_gpio, EC_SPI_CS, GPIO_PIN_HIGH); | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-ec_probe(device_t dev) | |||
-{ | |||
- | |||
- device_set_desc(dev, "Chromebook Embedded Controller"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-fill_checksum(uint8_t *data_out, int len) | |||
-{ | |||
- int res; | |||
- int i; | |||
- | |||
- res = 0; | |||
- for (i = 0; i < len; i++) { | |||
- res += data_out[i]; | |||
- } | |||
- | |||
- data_out[len] = (res & 0xff); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-int | |||
-ec_command(uint8_t cmd, uint8_t *dout, uint8_t dout_len, | |||
- uint8_t *dinp, uint8_t dinp_len) | |||
-{ | |||
- struct spi_command spi_cmd; | |||
- struct ec_softc *sc; | |||
- uint8_t *msg_dout; | |||
- uint8_t *msg_dinp; | |||
- int ret; | |||
- int i; | |||
- | |||
- memset(&spi_cmd, 0, sizeof(spi_cmd)); | |||
- | |||
- msg_dout = malloc(dout_len + 4, M_DEVBUF, M_NOWAIT | M_ZERO); | |||
- msg_dinp = malloc(dinp_len + 4, M_DEVBUF, M_NOWAIT | M_ZERO); | |||
- | |||
- spi_cmd.tx_cmd = msg_dout; | |||
- spi_cmd.rx_cmd = msg_dinp; | |||
- | |||
- if (ec_sc == NULL) | |||
- return (-1); | |||
- | |||
- sc = ec_sc; | |||
- | |||
- msg_dout[0] = EC_CMD_VERSION0; | |||
- msg_dout[1] = cmd; | |||
- msg_dout[2] = dout_len; | |||
- | |||
- for (i = 0; i < dout_len; i++) { | |||
- msg_dout[i + 3] = dout[i]; | |||
- } | |||
- | |||
- fill_checksum(msg_dout, dout_len + 3); | |||
- | |||
- assert_cs(sc, 1); | |||
- spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = dout_len + 4; | |||
- ret = SPIBUS_TRANSFER(device_get_paren | |||
- | |||
- /* Wait 0xec */ | |||
- for (i = 0; i < 1000; i++) { | |||
- DELAY(10); | |||
- msg_dout[0] = 0xff; | |||
- spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = 1; | |||
- SPIBUS_TRANSFER(device_get_paren | |||
- if (msg_dinp[0] == 0xec) | |||
- break; | |||
- } | |||
- | |||
- /* Get the rest */ | |||
- for (i = 0; i < (dout_len + 4); i++) | |||
- msg_dout[i] = 0xff; | |||
- spi_cmd.rx_cmd_sz = spi_cmd.tx_cmd_sz = dout_len + 4 - 1; | |||
- ret = SPIBUS_TRANSFER(device_get_paren | |||
- assert_cs(sc, 0); | |||
- | |||
- if (ret != 0) { | |||
- device_printf(sc->dev, "spibus_transfer returned %d\n", ret); | |||
- free(msg_dout, M_DEVBUF); | |||
- free(msg_dinp, M_DEVBUF); | |||
- return (-1); | |||
- } | |||
- | |||
- for (i = 0; i < dinp_len; i++) { | |||
- dinp[i] = msg_dinp[i + 2]; | |||
- } | |||
- | |||
- free(msg_dout, M_DEVBUF); | |||
- free(msg_dinp, M_DEVBUF); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-ec_attach(device_t dev) | |||
-{ | |||
- struct ec_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- sc->dev = dev; | |||
- | |||
- ec_sc = sc; | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-ec_detach(device_t dev) | |||
-{ | |||
- struct ec_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static device_method_t ec_methods[] = { | |||
- DEVMETHOD(device_probe, ec_probe), | |||
- DEVMETHOD(device_attach, ec_attach), | |||
- DEVMETHOD(device_detach, ec_detach), | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t ec_driver = { | |||
- "chrome_ec", | |||
- ec_methods, | |||
- sizeof(struct ec_softc), | |||
-}; | |||
- | |||
-static devclass_t ec_devclass; | |||
- | |||
-DRIVER_MODULE(chrome_ec, spibus, ec_driver, ec_devclass, 0, 0); | |||
-MODULE_VERSION(chrome_ec, 1); | |||
-MODULE_DEPEND(chrome_ec, spibus, 1, 1, 1); |
@@ -1,915 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Samsung Chromebook Keyboard | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/proc.h> | |||
-#include <sys/sched.h> | |||
-#include <sys/kdb.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/mutex.h> | |||
-#include <sys/gpio.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <sys/ioccom.h> | |||
-#include <sys/filio.h> | |||
-#include <sys/kbio.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include "gpio_if.h" | |||
- | |||
-#include <arm/samsung/exynos/chrome_ec.h> | |||
-#include <arm/samsung/exynos/chrome_kb.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_combiner | |||
-#include <arm/samsung/exynos/exynos5_pad.h> | |||
- | |||
-#define CKB_LOCK() mtx_lock(&Giant) | |||
-#define CKB_UNLOCK() mtx_unlock(&Giant) | |||
- | |||
-#ifdef INVARIANTS | |||
-/* | |||
- * Assert that the lock is held in all contexts | |||
- * where the code can be executed. | |||
- */ | |||
-#define CKB_LOCK_ASSERT() mtx_assert(&Giant, MA_OWNED) | |||
-/* | |||
- * Assert that the lock is held in the contexts | |||
- * where it really has to be so. | |||
- */ | |||
-#define CKB_CTX_LOCK_ASS | |||
- do { \ | |||
- if (!kdb_active && !KERNEL_PANICKED()) \ | |||
- mtx_assert(&Giant, MA_OWNED); \ | |||
- } while (0) | |||
-#else | |||
-#define CKB_LOCK_ASSERT() (void)0 | |||
-#define CKB_CTX_LOCK_ASS | |||
-#endif | |||
- | |||
-/* | |||
- * Define a stub keyboard driver in case one hasn't been | |||
- * compiled into the kernel | |||
- */ | |||
-#include <sys/kbio.h> | |||
-#include <dev/kbd/kbdreg.h> | |||
-#include <dev/kbd/kbdtables.h> | |||
- | |||
-#define CKB_NFKEY 12 | |||
-#define CKB_FLAG_COMPOSE | |||
-#define CKB_FLAG_POLLING | |||
-#define KBD_DRIVER_NAME "ckbd" | |||
- | |||
-struct ckb_softc { | |||
- keyboard_t sc_kbd; | |||
- keymap_t sc_keymap; | |||
- accentmap_t sc_accmap; | |||
- fkeytab_t sc_fkeymap[CKB_NFKEY]; | |||
- | |||
- struct resource* sc_mem_res; | |||
- struct resource* sc_irq_res; | |||
- void* sc_intr_hl; | |||
- | |||
- int sc_mode; /* input mode (K_XLATE,K_RAW,K_ | |||
- int sc_state; /* shift/lock key state */ | |||
- int sc_accents; /* accent key index (> 0) */ | |||
- int sc_flags; /* flags */ | |||
- | |||
- struct callout sc_repeat_callou | |||
- int sc_repeat_key; | |||
- int sc_repeating; | |||
- | |||
- int flag; | |||
- int rows; | |||
- int cols; | |||
- int gpio; | |||
- device_t dev; | |||
- device_t gpio_dev; | |||
- struct thread *sc_poll_thread; | |||
- uint16_t *keymap; | |||
- | |||
- uint8_t *scan_local; | |||
- uint8_t *scan; | |||
-}; | |||
- | |||
-/* prototypes */ | |||
-static int ckb_set_typemati | |||
-static uint32_t ckb_read_char(keyboard_t *, int); | |||
-static void ckb_clear_state(keyboard_t *); | |||
-static int ckb_ioctl(keyboard_t *, u_long, caddr_t); | |||
-static int ckb_enable(keyboard_t *); | |||
-static int ckb_disable(keyboard_t *); | |||
- | |||
-static void | |||
-ckb_repeat(void *arg) | |||
-{ | |||
- struct ckb_softc *sc; | |||
- | |||
- sc = arg; | |||
- | |||
- if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { | |||
- if (sc->sc_repeat_key != -1) { | |||
- sc->sc_repeating = 1; | |||
- sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, | |||
- KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); | |||
- } | |||
- } | |||
-} | |||
- | |||
-/* detect a keyboard, not used */ | |||
-static int | |||
-ckb__probe(int unit, void *arg, int flags) | |||
-{ | |||
- | |||
- return (ENXIO); | |||
-} | |||
- | |||
-/* reset and initialize the device, not used */ | |||
-static int | |||
-ckb_init(int unit, keyboard_t **kbdp, void *arg, int flags) | |||
-{ | |||
- | |||
- return (ENXIO); | |||
-} | |||
- | |||
-/* test the interface to the device, not used */ | |||
-static int | |||
-ckb_test_if(keyboard_t *kbd) | |||
-{ | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-/* finish using this keyboard, not used */ | |||
-static int | |||
-ckb_term(keyboard_t *kbd) | |||
-{ | |||
- | |||
- return (ENXIO); | |||
-} | |||
- | |||
-/* keyboard interrupt routine, not used */ | |||
-static int | |||
-ckb_intr(keyboard_t *kbd, void *arg) | |||
-{ | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-/* lock the access to the keyboard, not used */ | |||
-static int | |||
-ckb_lock(keyboard_t *kbd, int lock) | |||
-{ | |||
- | |||
- return (1); | |||
-} | |||
- | |||
-/* clear the internal state of the keyboard */ | |||
-static void | |||
-ckb_clear_state(keyboard_t *kbd) | |||
-{ | |||
- struct ckb_softc *sc; | |||
- | |||
- sc = kbd->kb_data; | |||
- | |||
- CKB_CTX_LOCK_ASS | |||
- | |||
- sc->sc_flags &= ~(CKB_FLAG_COMPOSE | |||
- sc->sc_state &= LOCK_MASK; /* preserve locking key state */ | |||
- sc->sc_accents = 0; | |||
-} | |||
- | |||
-/* save the internal state, not used */ | |||
-static int | |||
-ckb_get_state(keyboard_t *kbd, void *buf, size_t len) | |||
-{ | |||
- | |||
- return (len == 0) ? 1 : -1; | |||
-} | |||
- | |||
-/* set the internal state, not used */ | |||
-static int | |||
-ckb_set_state(keyboard_t *kbd, void *buf, size_t len) | |||
-{ | |||
- | |||
- return (EINVAL); | |||
-} | |||
- | |||
-/* check if data is waiting */ | |||
-static int | |||
-ckb_check(keyboard_t *kbd) | |||
-{ | |||
- struct ckb_softc *sc; | |||
- int i; | |||
- | |||
- sc = kbd->kb_data; | |||
- | |||
- CKB_CTX_LOCK_ASS | |||
- | |||
- if (!KBD_IS_ACTIVE(kbd)) | |||
- return (0); | |||
- | |||
- if (sc->sc_flags & CKB_FLAG_POLLING | |||
- return (1); | |||
- } | |||
- | |||
- for (i = 0; i < sc->cols; i++) | |||
- if (sc->scan_local[i] != sc->scan[i]) { | |||
- return (1); | |||
- } | |||
- | |||
- if (sc->sc_repeating) | |||
- return (1); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-/* check if char is waiting */ | |||
-static int | |||
-ckb_check_char_l | |||
-{ | |||
- CKB_CTX_LOCK_ASS | |||
- | |||
- if (!KBD_IS_ACTIVE(kbd)) | |||
- return (0); | |||
- | |||
- return (ckb_check(kbd)); | |||
-} | |||
- | |||
-static int | |||
-ckb_check_char(keyboard_t *kbd) | |||
-{ | |||
- int result; | |||
- | |||
- CKB_LOCK(); | |||
- result = ckb_check_char_l | |||
- CKB_UNLOCK(); | |||
- | |||
- return (result); | |||
-} | |||
- | |||
-/* read one byte from the keyboard if it's allowed */ | |||
-/* Currently unused. */ | |||
-static int | |||
-ckb_read(keyboard_t *kbd, int wait) | |||
-{ | |||
- CKB_CTX_LOCK_ASS | |||
- | |||
- if (!KBD_IS_ACTIVE(kbd)) | |||
- return (-1); | |||
- | |||
- printf("Implement ME: %s\n", __func__); | |||
- return (0); | |||
-} | |||
- | |||
-static uint16_t | |||
-keymap_read(struct ckb_softc *sc, int col, int row) | |||
-{ | |||
- | |||
- KASSERT(sc->keymap != NULL, ("keymap_read: no keymap")); | |||
- if (col >= 0 && col < sc->cols && | |||
- row >= 0 && row < sc->rows) { | |||
- return sc->keymap[row * sc->cols + col]; | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-keymap_write(struct ckb_softc *sc, int col, int row, uint16_t key) | |||
-{ | |||
- | |||
- KASSERT(sc->keymap != NULL, ("keymap_write: no keymap")); | |||
- if (col >= 0 && col < sc->cols && | |||
- row >= 0 && row < sc->rows) { | |||
- sc->keymap[row * sc->cols + col] = key; | |||
- return (0); | |||
- } | |||
- | |||
- return (-1); | |||
-} | |||
- | |||
-/* read char from the keyboard */ | |||
-static uint32_t | |||
-ckb_read_char_lo | |||
-{ | |||
- struct ckb_softc *sc; | |||
- int i,j; | |||
- uint16_t key; | |||
- int oldbit; | |||
- int newbit; | |||
- int status; | |||
- | |||
- sc = kbd->kb_data; | |||
- | |||
- CKB_CTX_LOCK_ASS | |||
- | |||
- if (!KBD_IS_ACTIVE(kbd)) | |||
- return (NOKEY); | |||
- | |||
- if (sc->sc_repeating) { | |||
- sc->sc_repeating = 0; | |||
- callout_reset(&sc->sc_repeat_callou | |||
- ckb_repeat, sc); | |||
- return (sc->sc_repeat_key); | |||
- } | |||
- | |||
- if (sc->sc_flags & CKB_FLAG_POLLING | |||
- for (;;) { | |||
- GPIO_PIN_GET(sc->gpio_dev, sc->gpio, &status); | |||
- if (status == 0) { | |||
- if (ec_command(EC_CMD_MKBP_STAT | |||
- sc->cols, | |||
- sc->scan, sc->cols)) { | |||
- return (NOKEY); | |||
- } | |||
- break; | |||
- } | |||
- if (!wait) { | |||
- return (NOKEY); | |||
- } | |||
- DELAY(1000); | |||
- } | |||
- } | |||
- | |||
- for (i = 0; i < sc->cols; i++) { | |||
- for (j = 0; j < sc->rows; j++) { | |||
- oldbit = (sc->scan_local[i] & (1 << j)); | |||
- newbit = (sc->scan[i] & (1 << j)); | |||
- | |||
- if (oldbit == newbit) | |||
- continue; | |||
- | |||
- key = keymap_read(sc, i, j); | |||
- if (key == 0) { | |||
- continue; | |||
- } | |||
- | |||
- if (newbit > 0) { | |||
- /* key pressed */ | |||
- sc->scan_local[i] |= (1 << j); | |||
- | |||
- /* setup repeating */ | |||
- sc->sc_repeat_key = key; | |||
- callout_reset(&sc->sc_repeat_callou | |||
- hz / 2, ckb_repeat, sc); | |||
- | |||
- } else { | |||
- /* key released */ | |||
- sc->scan_local[i] &= ~(1 << j); | |||
- | |||
- /* release flag */ | |||
- key |= 0x80; | |||
- | |||
- /* unsetup repeating */ | |||
- sc->sc_repeat_key = -1; | |||
- callout_stop(&sc->sc_repeat_callou | |||
- } | |||
- | |||
- return (key); | |||
- } | |||
- } | |||
- | |||
- return (NOKEY); | |||
-} | |||
- | |||
-/* Currently wait is always false. */ | |||
-static uint32_t | |||
-ckb_read_char(keyboard_t *kbd, int wait) | |||
-{ | |||
- uint32_t keycode; | |||
- | |||
- CKB_LOCK(); | |||
- keycode = ckb_read_char_lo | |||
- CKB_UNLOCK(); | |||
- | |||
- return (keycode); | |||
-} | |||
- | |||
-/* some useful control functions */ | |||
-static int | |||
-ckb_ioctl_locked | |||
-{ | |||
- struct ckb_softc *sc; | |||
- int i; | |||
- | |||
- sc = kbd->kb_data; | |||
- | |||
- CKB_LOCK_ASSERT(); | |||
- | |||
- switch (cmd) { | |||
- case KDGKBMODE: /* get keyboard mode */ | |||
- *(int *)arg = sc->sc_mode; | |||
- break; | |||
- | |||
- case KDSKBMODE: /* set keyboard mode */ | |||
- switch (*(int *)arg) { | |||
- case K_XLATE: | |||
- if (sc->sc_mode != K_XLATE) { | |||
- /* make lock key state and LED state match */ | |||
- sc->sc_state &= ~LOCK_MASK; | |||
- sc->sc_state |= KBD_LED_VAL(kbd); | |||
- } | |||
- /* FALLTHROUGH */ | |||
- case K_RAW: | |||
- case K_CODE: | |||
- if (sc->sc_mode != *(int *)arg) { | |||
- if ((sc->sc_flags & CKB_FLAG_POLLING | |||
- ckb_clear_state(kbd); | |||
- sc->sc_mode = *(int *)arg; | |||
- } | |||
- break; | |||
- default: | |||
- return (EINVAL); | |||
- } | |||
- break; | |||
- | |||
- case KDGETLED: /* get keyboard LED */ | |||
- *(int *)arg = KBD_LED_VAL(kbd); | |||
- break; | |||
- | |||
- case KDSETLED: /* set keyboard LED */ | |||
- /* NOTE: lock key state in "sc_state" won't be changed */ | |||
- if (*(int *)arg & ~LOCK_MASK) | |||
- return (EINVAL); | |||
- | |||
- i = *(int *)arg; | |||
- | |||
- /* replace CAPS LED with ALTGR LED for ALTGR keyboards */ | |||
- if (sc->sc_mode == K_XLATE && | |||
- kbd->kb_keymap->n_keys > ALTGR_OFFSET) { | |||
- if (i & ALKED) | |||
- i |= CLKED; | |||
- else | |||
- i &= ~CLKED; | |||
- } | |||
- if (KBD_HAS_DEVICE(kbd)) { | |||
- /* Configure LED */ | |||
- } | |||
- | |||
- KBD_LED_VAL(kbd) = *(int *)arg; | |||
- break; | |||
- case KDGKBSTATE: /* get lock key state */ | |||
- *(int *)arg = sc->sc_state & LOCK_MASK; | |||
- break; | |||
- | |||
- case KDSKBSTATE: /* set lock key state */ | |||
- if (*(int *)arg & ~LOCK_MASK) { | |||
- return (EINVAL); | |||
- } | |||
- sc->sc_state &= ~LOCK_MASK; | |||
- sc->sc_state |= *(int *)arg; | |||
- | |||
- /* set LEDs and quit */ | |||
- return (ckb_ioctl(kbd, KDSETLED, arg)); | |||
- | |||
- case KDSETREPEAT: /* set keyboard repeat rate (new | |||
- * interface) */ | |||
- | |||
- if (!KBD_HAS_DEVICE(kbd)) { | |||
- return (0); | |||
- } | |||
- if (((int *)arg)[1] < 0) { | |||
- return (EINVAL); | |||
- } | |||
- if (((int *)arg)[0] < 0) { | |||
- return (EINVAL); | |||
- } | |||
- if (((int *)arg)[0] < 200) /* fastest possible value */ | |||
- kbd->kb_delay1 = 200; | |||
- else | |||
- kbd->kb_delay1 = ((int *)arg)[0]; | |||
- kbd->kb_delay2 = ((int *)arg)[1]; | |||
- return (0); | |||
- | |||
- case KDSETRAD: /* set keyboard repeat rate (old | |||
- * interface) */ | |||
- return (ckb_set_typemati | |||
- | |||
- case PIO_KEYMAP: /* set keyboard translation table */ | |||
- case OPIO_KEYMAP: /* set keyboard translation table | |||
- * (compat) */ | |||
- case PIO_KEYMAPENT: /* set keyboard translation table | |||
- * entry */ | |||
- case PIO_DEADKEYMAP: /* set accent key translation table */ | |||
- sc->sc_accents = 0; | |||
- /* FALLTHROUGH */ | |||
- default: | |||
- return (genkbd_commonioc | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-ckb_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) | |||
-{ | |||
- int result; | |||
- | |||
- /* | |||
- * XXX KDGKBSTATE, KDSKBSTATE and KDSETLED can be called from any | |||
- * context where printf(9) can be called, which among other things | |||
- * includes interrupt filters and threads with any kinds of locks | |||
- * already held. For this reason it would be dangerous to acquire | |||
- * the Giant here unconditionally. On the other hand we have to | |||
- * have it to handle the ioctl. | |||
- * So we make our best effort to auto-detect whether we can grab | |||
- * the Giant or not. Blame syscons(4) for this. | |||
- */ | |||
- switch (cmd) { | |||
- case KDGKBSTATE: | |||
- case KDSKBSTATE: | |||
- case KDSETLED: | |||
- if (!mtx_owned(&Giant) && !SCHEDULER_STOPPE | |||
- return (EDEADLK); /* best I could come up with */ | |||
- /* FALLTHROUGH */ | |||
- default: | |||
- CKB_LOCK(); | |||
- result = ckb_ioctl_locked | |||
- CKB_UNLOCK(); | |||
- return (result); | |||
- } | |||
-} | |||
- | |||
-/* | |||
- * Enable the access to the device; until this function is called, | |||
- * the client cannot read from the keyboard. | |||
- */ | |||
-static int | |||
-ckb_enable(keyboard_t *kbd) | |||
-{ | |||
- | |||
- CKB_LOCK(); | |||
- KBD_ACTIVATE(kbd); | |||
- CKB_UNLOCK(); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-/* disallow the access to the device */ | |||
-static int | |||
-ckb_disable(keyboard_t *kbd) | |||
-{ | |||
- | |||
- CKB_LOCK(); | |||
- KBD_DEACTIVATE(kbd); | |||
- CKB_UNLOCK(); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-/* local functions */ | |||
- | |||
-static int | |||
-ckb_set_typemati | |||
-{ | |||
- static const int delays[] = {250, 500, 750, 1000}; | |||
- static const int rates[] = {34, 38, 42, 46, 50, 55, 59, 63, | |||
- 68, 76, 84, 92, 100, 110, 118, 126, | |||
- 136, 152, 168, 184, 200, 220, 236, 252, | |||
- 272, 304, 336, 368, 400, 440, 472, 504}; | |||
- | |||
- if (code & ~0x7f) { | |||
- return (EINVAL); | |||
- } | |||
- kbd->kb_delay1 = delays[(code >> 5) & 3]; | |||
- kbd->kb_delay2 = rates[code & 0x1f]; | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-ckb_poll(keyboard_t *kbd, int on) | |||
-{ | |||
- struct ckb_softc *sc; | |||
- | |||
- sc = kbd->kb_data; | |||
- | |||
- CKB_LOCK(); | |||
- if (on) { | |||
- sc->sc_flags |= CKB_FLAG_POLLING | |||
- sc->sc_poll_thread = curthread; | |||
- } else { | |||
- sc->sc_flags &= ~CKB_FLAG_POLLING | |||
- } | |||
- CKB_UNLOCK(); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-/* local functions */ | |||
- | |||
-static int dummy_kbd_config | |||
- | |||
-keyboard_switch_ | |||
- .probe = &ckb__probe, | |||
- .init = &ckb_init, | |||
- .term = &ckb_term, | |||
- .intr = &ckb_intr, | |||
- .test_if = &ckb_test_if, | |||
- .enable = &ckb_enable, | |||
- .disable = &ckb_disable, | |||
- .read = &ckb_read, | |||
- .check = &ckb_check, | |||
- .read_char = &ckb_read_char, | |||
- .check_char = &ckb_check_char, | |||
- .ioctl = &ckb_ioctl, | |||
- .lock = &ckb_lock, | |||
- .clear_state = &ckb_clear_state, | |||
- .get_state = &ckb_get_state, | |||
- .set_state = &ckb_set_state, | |||
- .poll = &ckb_poll, | |||
-}; | |||
- | |||
-static int | |||
-dummy_kbd_config | |||
-{ | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-KEYBOARD_DRIVER(ckbd, ckbdsw, dummy_kbd_config | |||
- | |||
-/* | |||
- * Parses 'keymap' into sc->keymap. | |||
- * Requires sc->cols and sc->rows to be set. | |||
- */ | |||
-static int | |||
-parse_keymap(struct ckb_softc *sc, pcell_t *keymap, size_t len) | |||
-{ | |||
- int i; | |||
- | |||
- sc->keymap = malloc(sc->cols * sc->rows * sizeof(sc->keymap[0]), | |||
- M_DEVBUF, M_NOWAIT | M_ZERO); | |||
- if (sc->keymap == NULL) { | |||
- return (ENOMEM); | |||
- } | |||
- | |||
- for (i = 0; i < len; i++) { | |||
- /* | |||
- * Return value is ignored, we just write whatever fits into | |||
- * specified number of rows and columns and silently ignore | |||
- * everything else. | |||
- * Keymap entries follow this format: 0xRRCCKKKK | |||
- * RR - row number, CC - column number, KKKK - key code | |||
- */ | |||
- keymap_write(sc, (keymap[i] >> 16) & 0xff, | |||
- (keymap[i] >> 24) & 0xff, | |||
- keymap[i] & 0xffff); | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-/* Allocates a new array for keymap and returns it in 'keymap'. */ | |||
-static int | |||
-read_keymap(phandle_t node, const char *prop, pcell_t **keymap, size_t *len) | |||
-{ | |||
- | |||
- if ((*len = OF_getproplen(node, prop)) <= 0) { | |||
- return (ENXIO); | |||
- } | |||
- if ((*keymap = malloc(*len, M_DEVBUF, M_NOWAIT)) == NULL) { | |||
- return (ENOMEM); | |||
- } | |||
- if (OF_getencprop(node, prop, *keymap, *len) != *len) { | |||
- return (ENXIO); | |||
- } | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-parse_dts(struct ckb_softc *sc) | |||
-{ | |||
- phandle_t node; | |||
- pcell_t dts_value; | |||
- pcell_t *keymap; | |||
- int len, ret; | |||
- const char *keymap_prop = NULL; | |||
- | |||
- if ((node = ofw_bus_get_node | |||
- return (ENXIO); | |||
- | |||
- if ((len = OF_getproplen(node, "google,key-rows")) <= 0) | |||
- return (ENXIO); | |||
- OF_getencprop(node, "google,key-rows", &dts_value, len); | |||
- sc->rows = dts_value; | |||
- | |||
- if ((len = OF_getproplen(node, "google,key-columns")) <= 0) | |||
- return (ENXIO); | |||
- OF_getencprop(node, "google,key-columns", &dts_value, len); | |||
- sc->cols = dts_value; | |||
- | |||
- if ((len = OF_getproplen(node, "freebsd,intr-gpio")) <= 0) | |||
- return (ENXIO); | |||
- OF_getencprop(node, "freebsd,intr-gpio", &dts_value, len); | |||
- sc->gpio = dts_value; | |||
- | |||
- if (OF_hasprop(node, "freebsd,keymap")) { | |||
- keymap_prop = "freebsd,keymap"; | |||
- device_printf(sc->dev, "using FreeBSD-specific keymap from FDT\n"); | |||
- } else if (OF_hasprop(node, "linux,keymap")) { | |||
- keymap_prop = "linux,keymap"; | |||
- device_printf(sc->dev, "using Linux keymap from FDT\n"); | |||
- } else { | |||
- device_printf(sc->dev, "using built-in keymap\n"); | |||
- } | |||
- | |||
- if (keymap_prop != NULL) { | |||
- if ((ret = read_keymap(node, keymap_prop, &keymap, &len))) { | |||
- device_printf(sc->dev, | |||
- "failed to read keymap from FDT: %d\n", ret); | |||
- return (ret); | |||
- } | |||
- ret = parse_keymap(sc, keymap, len); | |||
- free(keymap, M_DEVBUF); | |||
- if (ret) { | |||
- return (ret); | |||
- } | |||
- } else { | |||
- if ((ret = parse_keymap(sc, default_keymap, KEYMAP_LEN))) { | |||
- return (ret); | |||
- } | |||
- } | |||
- | |||
- if ((sc->rows == 0) || (sc->cols == 0) || (sc->gpio == 0)) | |||
- return (ENXIO); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-void | |||
-ckb_ec_intr(void *arg) | |||
-{ | |||
- struct ckb_softc *sc; | |||
- | |||
- sc = arg; | |||
- | |||
- if (sc->sc_flags & CKB_FLAG_POLLING | |||
- return; | |||
- | |||
- ec_command(EC_CMD_MKBP_STAT | |||
- sc->scan, sc->cols); | |||
- | |||
- (sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT, | |||
- sc->sc_kbd.kb_callback.kc_arg); | |||
-}; | |||
- | |||
-static int | |||
-chrome_kb_attach | |||
-{ | |||
- struct ckb_softc *sc; | |||
- keyboard_t *kbd; | |||
- int error; | |||
- int rid; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- sc->dev = dev; | |||
- sc->keymap = NULL; | |||
- | |||
- if ((error = parse_dts(sc)) != 0) | |||
- return error; | |||
- | |||
- sc->gpio_dev = devclass_get_dev | |||
- if (sc->gpio_dev == NULL) { | |||
- device_printf(sc->dev, "Can't find gpio device.\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
-#if 0 | |||
- device_printf(sc->dev, "Keyboard matrix [%dx%d]\n", | |||
- sc->cols, sc->rows); | |||
-#endif | |||
- | |||
- pad_setup_intr(sc->gpio, ckb_ec_intr, sc); | |||
- | |||
- kbd = &sc->sc_kbd; | |||
- rid = 0; | |||
- | |||
- sc->scan_local = malloc(sc->cols, M_DEVBUF, M_NOWAIT); | |||
- sc->scan = malloc(sc->cols, M_DEVBUF, M_NOWAIT); | |||
- | |||
- for (i = 0; i < sc->cols; i++) { | |||
- sc->scan_local[i] = 0; | |||
- sc->scan[i] = 0; | |||
- } | |||
- | |||
- kbd_init_struct(kbd, KBD_DRIVER_NAME, | |||
- device_get_unit(dev), 0, 0, 0); | |||
- kbd->kb_data = (void *)sc; | |||
- | |||
- sc->sc_keymap = key_map; | |||
- sc->sc_accmap = accent_map; | |||
- for (i = 0; i < CKB_NFKEY; i++) { | |||
- sc->sc_fkeymap[i] = fkey_tab[i]; | |||
- } | |||
- | |||
- kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap, | |||
- sc->sc_fkeymap, CKB_NFKEY); | |||
- | |||
- KBD_FOUND_DEVICE | |||
- ckb_clear_state(kbd); | |||
- KBD_PROBE_DONE(kbd); | |||
- | |||
- callout_init(&sc->sc_repeat_callou | |||
- | |||
- KBD_INIT_DONE(kbd); | |||
- | |||
- if (kbd_register(kbd) < 0) { | |||
- return (ENXIO); | |||
- } | |||
- KBD_CONFIG_DONE(kbd); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-chrome_kb_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (ofw_bus_is_compa | |||
- ofw_bus_is_compa | |||
- device_set_desc(dev, "Chrome EC Keyboard"); | |||
- return (BUS_PROBE_DEFAUL | |||
- } | |||
- | |||
- return (ENXIO); | |||
-} | |||
- | |||
-static int | |||
-chrome_kb_detach | |||
-{ | |||
- struct ckb_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- if (sc->keymap != NULL) { | |||
- free(sc->keymap, M_DEVBUF); | |||
- } | |||
- | |||
- return 0; | |||
-} | |||
- | |||
-static device_method_t chrome_kb_method | |||
- DEVMETHOD(device_probe, chrome_kb_probe), | |||
- DEVMETHOD(device_attach, chrome_kb_attach | |||
- DEVMETHOD(device_detach, chrome_kb_detach | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t chrome_kb_driver | |||
- "chrome_kb", | |||
- chrome_kb_method | |||
- sizeof(struct ckb_softc), | |||
-}; | |||
- | |||
-static devclass_t chrome_kb_devcla | |||
- | |||
-DRIVER_MODULE(chrome_kb, simplebus, chrome_kb_driver | |||
- chrome_kb_devcla |
@@ -1,118 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- * | |||
- * $FreeBSD$ | |||
- */ | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
- | |||
-void ckb_ec_intr(void *); | |||
- | |||
-#define KEYMAP_LEN 75 | |||
- | |||
-pcell_t default_keymap[KEYMAP_LEN] = { | |||
- 0x0001007d, /* lmeta */ | |||
- 0x0002003b, /* F1 */ | |||
- 0x00030030, /* B */ | |||
- 0x00040044, /* F10 */ | |||
- 0x00060031, /* N */ | |||
- 0x0008000d, /* = */ | |||
- 0x000a0064, /* ralt */ | |||
- | |||
- 0x01010001, /* escape */ | |||
- 0x0102003e, /* F4 */ | |||
- 0x01030022, /* G */ | |||
- 0x01040041, /* F7 */ | |||
- 0x01060023, /* H */ | |||
- 0x01080028, /* ' */ | |||
- 0x01090043, /* F9 */ | |||
- 0x010b000e, /* backspace */ | |||
- | |||
- 0x0200001d, /* lctrl */ | |||
- 0x0201000f, /* tab */ | |||
- 0x0202003d, /* F3 */ | |||
- 0x02030014, /* t */ | |||
- 0x02040040, /* F6 */ | |||
- 0x0205001b, /* ] */ | |||
- 0x02060015, /* y */ | |||
- 0x02070056, /* 102nd */ | |||
- 0x0208001a, /* [ */ | |||
- 0x02090042, /* F8 */ | |||
- | |||
- 0x03010029, /* grave */ | |||
- 0x0302003c, /* F2 */ | |||
- 0x03030006, /* 5 */ | |||
- 0x0304003f, /* F5 */ | |||
- 0x03060007, /* 6 */ | |||
- 0x0308000c, /* - */ | |||
- 0x030b002b, /* \ */ | |||
- | |||
- 0x04000061, /* rctrl */ | |||
- 0x0401001e, /* a */ | |||
- 0x04020020, /* d */ | |||
- 0x04030021, /* f */ | |||
- 0x0404001f, /* s */ | |||
- 0x04050025, /* k */ | |||
- 0x04060024, /* j */ | |||
- 0x04080027, /* ; */ | |||
- 0x04090026, /* l */ | |||
- 0x040a002b, /* \ */ | |||
- 0x040b001c, /* enter */ | |||
- | |||
- 0x0501002c, /* z */ | |||
- 0x0502002e, /* c */ | |||
- 0x0503002f, /* v */ | |||
- 0x0504002d, /* x */ | |||
- 0x05050033, /* , */ | |||
- 0x05060032, /* m */ | |||
- 0x0507002a, /* lsh */ | |||
- 0x05080035, /* / */ | |||
- 0x05090034, /* . */ | |||
- 0x050B0039, /* space */ | |||
- | |||
- 0x06010002, /* 1 */ | |||
- 0x06020004, /* 3 */ | |||
- 0x06030005, /* 4 */ | |||
- 0x06040003, /* 2 */ | |||
- 0x06050009, /* 8 */ | |||
- 0x06060008, /* 7 */ | |||
- 0x0608000b, /* 0 */ | |||
- 0x0609000a, /* 9 */ | |||
- 0x060a0038, /* lalt */ | |||
- 0x060b0064, /* down */ | |||
- 0x060c0062, /* right */ | |||
- | |||
- 0x07010010, /* q */ | |||
- 0x07020012, /* e */ | |||
- 0x07030013, /* r */ | |||
- 0x07040011, /* w */ | |||
- 0x07050017, /* i */ | |||
- 0x07060016, /* u */ | |||
- 0x07070036, /* rsh */ | |||
- 0x07080019, /* p */ | |||
- 0x07090018, /* o */ | |||
- 0x070b005F, /* up */ | |||
- 0x070c0061, /* left */ | |||
-}; |
@@ -1,415 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Samsung Exynos 5 Interrupt Combiner | |||
- * Chapter 7, Exynos 5 Dual User's Manual Public Rev 1.00 | |||
- */ | |||
-#ifdef USB_GLOBAL_INCLU | |||
-#include USB_GLOBAL_INCLU | |||
-#else | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
-#endif | |||
- | |||
-#include <arm/samsung/exynos/exynos5_common.h> | |||
-#include <arm/samsung/exynos/exynos5_combiner | |||
- | |||
-#define NGRP 32 | |||
- | |||
-#define IESR(n) (0x10 * n + 0x0) /* Interrupt enable set */ | |||
-#define IECR(n) (0x10 * n + 0x4) /* Interrupt enable clear */ | |||
-#define ISTR(n) (0x10 * n + 0x8) /* Interrupt status */ | |||
-#define IMSR(n) (0x10 * n + 0xC) /* Interrupt masked status */ | |||
-#define CIPSR 0x100 /* Combined interrupt pending */ | |||
- | |||
-struct combiner_softc { | |||
- struct resource *res[1 + NGRP]; | |||
- bus_space_tag_t bst; | |||
- bus_space_handle | |||
- void *ih[NGRP]; | |||
- device_t dev; | |||
-}; | |||
- | |||
-struct combiner_softc *combiner_sc; | |||
- | |||
-static struct resource_spec combiner_spec[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 0, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 1, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 2, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 3, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 4, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 5, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 6, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 7, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 8, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 9, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 10, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 11, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 12, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 13, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 14, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 15, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 16, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 17, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 18, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 19, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 20, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 21, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 22, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 23, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 24, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 25, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 26, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 27, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 28, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 29, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 30, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 31, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-struct combiner_entry { | |||
- int combiner_id; | |||
- int bit; | |||
- char *source_name; | |||
-}; | |||
- | |||
-static struct combiner_entry interrupt_table[] = { | |||
- { 63, 1, "EINT[15]" }, | |||
- { 63, 0, "EINT[14]" }, | |||
- { 62, 1, "EINT[13]" }, | |||
- { 62, 0, "EINT[12]" }, | |||
- { 61, 1, "EINT[11]" }, | |||
- { 61, 0, "EINT[10]" }, | |||
- { 60, 1, "EINT[9]" }, | |||
- { 60, 0, "EINT[8]" }, | |||
- { 59, 1, "EINT[7]" }, | |||
- { 59, 0, "EINT[6]" }, | |||
- { 58, 1, "EINT[5]" }, | |||
- { 58, 0, "EINT[4]" }, | |||
- { 57, 3, "MCT_G3" }, | |||
- { 57, 2, "MCT_G2" }, | |||
- { 57, 1, "EINT[3]" }, | |||
- { 57, 0, "EINT[2]" }, | |||
- { 56, 6, "SYSMMU_G2D[1]" }, | |||
- { 56, 5, "SYSMMU_G2D[0]" }, | |||
- { 56, 2, "SYSMMU_FIMC_LITE | |||
- { 56, 1, "SYSMMU_FIMC_LITE | |||
- { 56, 0, "EINT[1]" }, | |||
- { 55, 4, "MCT_G1" }, | |||
- { 55, 3, "MCT_G0" }, | |||
- { 55, 0, "EINT[0]" }, | |||
- { 54, 7, "CPU_nCNTVIRQ[1]" }, | |||
- { 54, 6, "CPU_nCTIIRQ[1]" }, | |||
- { 54, 5, "CPU_nCNTPSIRQ[1]" }, | |||
- { 54, 4, "CPU_nPMUIRQ[1]" }, | |||
- { 54, 3, "CPU_nCNTPNSIRQ[1]" }, | |||
- { 54, 2, "CPU_PARITYFAILSC | |||
- { 54, 1, "CPU_nCNTHPIRQ[1]" }, | |||
- { 54, 0, "PARITYFAIL[1]" }, | |||
- { 53, 1, "CPU_nIRQ[1]" }, | |||
- { 52, 0, "CPU_nIRQ[0]" }, | |||
- { 51, 7, "CPU_nRAMERRIRQ" }, | |||
- { 51, 6, "CPU_nAXIERRIRQ" }, | |||
- { 51, 4, "INT_COMB_ISP_GIC | |||
- { 51, 3, "INT_COMB_IOP_GIC | |||
- { 51, 2, "CCI_nERRORIRQ" }, | |||
- { 51, 1, "INT_COMB_ARMISP_ | |||
- { 51, 0, "INT_COMB_ARMIOP_ | |||
- { 50, 7, "DISP1[3]" }, | |||
- { 50, 6, "DISP1[2]" }, | |||
- { 50, 5, "DISP1[1]" }, | |||
- { 50, 4, "DISP1[0]" }, | |||
- { 49, 3, "SSCM_PULSE_IRQ_C | |||
- { 49, 2, "SSCM_PULSE_IRQ_C | |||
- { 49, 1, "SSCM_IRQ_C2CIF[1]" }, | |||
- { 49, 0, "SSCM_IRQ_C2CIF[0]" }, | |||
- { 48, 3, "PEREV_M1_CDREX" }, | |||
- { 48, 2, "PEREV_M0_CDREX" }, | |||
- { 48, 1, "PEREV_A1_CDREX" }, | |||
- { 48, 0, "PEREV_A0_CDREX" }, | |||
- { 47, 3, "MDMA0_ABORT" }, | |||
- /* 46 is fully reserved */ | |||
- { 45, 1, "MDMA1_ABORT" }, | |||
- /* 44 is fully reserved */ | |||
- { 43, 7, "SYSMMU_DRCISP[1]" }, | |||
- { 43, 6, "SYSMMU_DRCISP[0]" }, | |||
- { 43, 1, "SYSMMU_ODC[1]" }, | |||
- { 43, 0, "SYSMMU_ODC[0]" }, | |||
- { 42, 7, "SYSMMU_ISP[1]" }, | |||
- { 42, 6, "SYSMMU_ISP[0]" }, | |||
- { 42, 5, "SYSMMU_DIS0[1]" }, | |||
- { 42, 4, "SYSMMU_DIS0[0]" }, | |||
- { 42, 3, "DP1" }, | |||
- { 41, 5, "SYSMMU_DIS1[1]" }, | |||
- { 41, 4, "SYSMMU_DIS1[0]" }, | |||
- { 40, 6, "SYSMMU_MFCL[1]" }, | |||
- { 40, 5, "SYSMMU_MFCL[0]" }, | |||
- { 39, 5, "SYSMMU_TV_M0[1]" }, | |||
- { 39, 4, "SYSMMU_TV_M0[0]" }, | |||
- { 39, 3, "SYSMMU_MDMA1[1]" }, | |||
- { 39, 2, "SYSMMU_MDMA1[0]" }, | |||
- { 39, 1, "SYSMMU_MDMA0[1]" }, | |||
- { 39, 0, "SYSMMU_MDMA0[0]" }, | |||
- { 38, 7, "SYSMMU_SSS[1]" }, | |||
- { 38, 6, "SYSMMU_SSS[0]" }, | |||
- { 38, 5, "SYSMMU_RTIC[1]" }, | |||
- { 38, 4, "SYSMMU_RTIC[0]" }, | |||
- { 38, 3, "SYSMMU_MFCR[1]" }, | |||
- { 38, 2, "SYSMMU_MFCR[0]" }, | |||
- { 38, 1, "SYSMMU_ARM[1]" }, | |||
- { 38, 0, "SYSMMU_ARM[0]" }, | |||
- { 37, 7, "SYSMMU_3DNR[1]" }, | |||
- { 37, 6, "SYSMMU_3DNR[0]" }, | |||
- { 37, 5, "SYSMMU_MCUISP[1]" }, | |||
- { 37, 4, "SYSMMU_MCUISP[0]" }, | |||
- { 37, 3, "SYSMMU_SCALERCIS | |||
- { 37, 2, "SYSMMU_SCALERCIS | |||
- { 37, 1, "SYSMMU_FDISP[1]" }, | |||
- { 37, 0, "SYSMMU_FDISP[0]" }, | |||
- { 36, 7, "MCUIOP_CTIIRQ" }, | |||
- { 36, 6, "MCUIOP_PMUIRQ" }, | |||
- { 36, 5, "MCUISP_CTIIRQ" }, | |||
- { 36, 4, "MCUISP_PMUIRQ" }, | |||
- { 36, 3, "SYSMMU_JPEGX[1]" }, | |||
- { 36, 2, "SYSMMU_JPEGX[0]" }, | |||
- { 36, 1, "SYSMMU_ROTATOR[1]" }, | |||
- { 36, 0, "SYSMMU_ROTATOR[0]" }, | |||
- { 35, 7, "SYSMMU_SCALERPIS | |||
- { 35, 6, "SYSMMU_SCALERPIS | |||
- { 35, 5, "SYSMMU_FIMC_LITE | |||
- { 35, 4, "SYSMMU_FIMC_LITE | |||
- { 35, 3, "SYSMMU_DISP1_M0[1]" }, | |||
- { 35, 2, "SYSMMU_DISP1_M0[0]" }, | |||
- { 35, 1, "SYSMMU_FIMC_LITE | |||
- { 35, 0, "SYSMMU_FIMC_LITE | |||
- { 34, 7, "SYSMMU_GSCL3[1]" }, | |||
- { 34, 6, "SYSMMU_GSCL3[0]" }, | |||
- { 34, 5, "SYSMMU_GSCL2[1]" }, | |||
- { 34, 4, "SYSMMU_GSCL2[0]" }, | |||
- { 34, 3, "SYSMMU_GSCL1[1]" }, | |||
- { 34, 2, "SYSMMU_GSCL1[0]" }, | |||
- { 34, 1, "SYSMMU_GSCL0[1]" }, | |||
- { 34, 0, "SYSMMU_GSCL0[0]" }, | |||
- { 33, 7, "CPU_nCNTVIRQ[0]" }, | |||
- { 33, 6, "CPU_nCNTPSIRQ[0]" }, | |||
- { 33, 5, "CPU_nCNTPSNIRQ[0]" }, | |||
- { 33, 4, "CPU_nCNTHPIRQ[0]" }, | |||
- { 33, 3, "CPU_nCTIIRQ[0]" }, | |||
- { 33, 2, "CPU_nPMUIRQ[0]" }, | |||
- { 33, 1, "CPU_PARITYFAILSC | |||
- { 33, 0, "CPU_PARITYFAIL0" }, | |||
- { 32, 7, "TZASC_XR1BXW" }, | |||
- { 32, 6, "TZASC_XR1BXR" }, | |||
- { 32, 5, "TZASC_XLBXW" }, | |||
- { 32, 4, "TZASC_XLBXR" }, | |||
- { 32, 3, "TZASC_DRBXW" }, | |||
- { 32, 2, "TZASC_DRBXR" }, | |||
- { 32, 1, "TZASC_CBXW" }, | |||
- { 32, 0, "TZASC_CBXR" }, | |||
- | |||
- { -1, -1, NULL }, | |||
-}; | |||
- | |||
-struct combined_intr { | |||
- uint32_t enabled; | |||
- void (*ih) (void *); | |||
- void *ih_user; | |||
-}; | |||
- | |||
-static struct combined_intr intr_map[32][8]; | |||
- | |||
-static void | |||
-combiner_intr(void *arg) | |||
-{ | |||
- struct combiner_softc *sc; | |||
- void (*ih) (void *); | |||
- void *ih_user; | |||
- int enabled; | |||
- int intrs; | |||
- int shift; | |||
- int cirq; | |||
- int grp; | |||
- int i,n; | |||
- | |||
- sc = arg; | |||
- | |||
- intrs = READ4(sc, CIPSR); | |||
- for (grp = 0; grp < 32; grp++) { | |||
- if (intrs & (1 << grp)) { | |||
- n = (grp / 4); | |||
- shift = (grp % 4) * 8; | |||
- | |||
- cirq = READ4(sc, ISTR(n)); | |||
- for (i = 0; i < 8; i++) { | |||
- if (cirq & (1 << (i + shift))) { | |||
- ih = intr_map[grp][i].ih; | |||
- ih_user = intr_map[grp][i].ih_user; | |||
- enabled = intr_map[grp][i].enabled; | |||
- if (enabled && (ih != NULL)) { | |||
- ih(ih_user); | |||
- } | |||
- } | |||
- } | |||
- } | |||
- } | |||
-} | |||
- | |||
-void | |||
-combiner_setup_i | |||
-{ | |||
- struct combiner_entry *entry; | |||
- struct combined_intr *cirq; | |||
- struct combiner_softc *sc; | |||
- int shift; | |||
- int reg; | |||
- int grp; | |||
- int n; | |||
- int i; | |||
- | |||
- sc = combiner_sc; | |||
- | |||
- if (sc == NULL) { | |||
- printf("%s: error: combiner is not attached\n", __func__); | |||
- return; | |||
- } | |||
- | |||
- entry = NULL; | |||
- | |||
- for (i = 0; i < NGRP && interrupt_table[i].bit != -1; i++) { | |||
- if (strcmp(interrupt_table[i].source_name, source_name) == 0) { | |||
- entry = &interrupt_table[i]; | |||
- } | |||
- } | |||
- | |||
- if (entry == NULL) { | |||
- device_printf(sc->dev, "Can't find interrupt name %s\n", | |||
- source_name); | |||
- return; | |||
- } | |||
- | |||
-#if 0 | |||
- device_printf(sc->dev, "Setting up interrupt %s\n", source_name); | |||
-#endif | |||
- | |||
- grp = entry->combiner_id - 32; | |||
- | |||
- cirq = &intr_map[grp][entry->bit]; | |||
- cirq->enabled = 1; | |||
- cirq->ih = ih; | |||
- cirq->ih_user = ih_user; | |||
- | |||
- n = grp / 4; | |||
- shift = (grp % 4) * 8 + entry->bit; | |||
- | |||
- reg = (1 << shift); | |||
- WRITE4(sc, IESR(n), reg); | |||
-} | |||
- | |||
-static int | |||
-combiner_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (!ofw_bus_is_compa | |||
- return (ENXIO); | |||
- | |||
- device_set_desc(dev, "Samsung Exynos 5 Interrupt Combiner"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-combiner_attach(device_t dev) | |||
-{ | |||
- struct combiner_softc *sc; | |||
- int err; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- sc->dev = dev; | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* Memory interface */ | |||
- sc->bst = rman_get_bustag(sc->res[0]); | |||
- sc->bsh = rman_get_bushand | |||
- | |||
- combiner_sc = sc; | |||
- | |||
- /* Setup interrupt handler */ | |||
- for (i = 0; i < NGRP; i++) { | |||
- err = bus_setup_intr(dev, sc->res[1+i], INTR_TYPE_BIO | \ | |||
- INTR_MPSAFE, NULL, combiner_intr, sc, &sc->ih[i]); | |||
- if (err) { | |||
- device_printf(dev, "Unable to alloc int resource.\n"); | |||
- return (ENXIO); | |||
- } | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static device_method_t combiner_methods | |||
- DEVMETHOD(device_probe, combiner_probe), | |||
- DEVMETHOD(device_attach, combiner_attach), | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t combiner_driver = { | |||
- "combiner", | |||
- combiner_methods | |||
- sizeof(struct combiner_softc), | |||
-}; | |||
- | |||
-static devclass_t combiner_devclas | |||
- | |||
-DRIVER_MODULE(combiner, simplebus, combiner_driver, |
@@ -1,29 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- * | |||
- * $FreeBSD$ | |||
- */ | |||
- | |||
-void combiner_setup_i |
@@ -1,40 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- * | |||
- * $FreeBSD$ | |||
- */ | |||
- | |||
-#define READ4(_sc, _reg) \ | |||
- bus_space_read_4 | |||
-#define WRITE4(_sc, _reg, _val) \ | |||
- bus_space_write_ | |||
-#define READ2(_sc, _reg) \ | |||
- bus_space_read_2 | |||
-#define WRITE2(_sc, _reg, _val) \ | |||
- bus_space_write_ | |||
-#define READ1(_sc, _reg) \ | |||
- bus_space_read_1 | |||
-#define WRITE1(_sc, _reg, _val) \ | |||
- bus_space_write_ |
@@ -1,397 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2013-2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-#ifdef USB_GLOBAL_INCLU | |||
-#include USB_GLOBAL_INCLU | |||
-#else | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include "opt_bus.h" | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/condvar.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/gpio.h> | |||
- | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <dev/usb/usb.h> | |||
-#include <dev/usb/usbdi.h> | |||
-#include <dev/usb/usb_busdma.h> | |||
-#include <dev/usb/usb_process.h> | |||
-#include <dev/usb/usb_controller.h> | |||
-#include <dev/usb/usb_bus.h> | |||
-#include <dev/usb/controller/ehci.h> | |||
-#include <dev/usb/controller/ehcireg.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/resource.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_common.h> | |||
-#include <arm/samsung/exynos/exynos5_pmu.h> | |||
- | |||
-#include "gpio_if.h" | |||
- | |||
-#include "opt_platform.h" | |||
-#endif | |||
- | |||
-/* GPIO control */ | |||
-#define GPIO_OUTPUT 1 | |||
-#define GPIO_INPUT 0 | |||
-#define PIN_USB 161 | |||
- | |||
-/* SYSREG */ | |||
-#define EXYNOS5_SYSREG_U | |||
-#define USB2_MODE_HOST 0x1 | |||
- | |||
-/* USB HOST */ | |||
-#define HOST_CTRL_CLK_24 | |||
-#define HOST_CTRL_CLK_MA | |||
-#define HOST_CTRL_SIDDQ (1 << 6) | |||
-#define HOST_CTRL_SLEEP (1 << 5) | |||
-#define HOST_CTRL_SUSPEN | |||
-#define HOST_CTRL_RESET_ | |||
-#define HOST_CTRL_RESET_ | |||
-#define HOST_CTRL_RESET_ | |||
- | |||
-/* Forward declarations */ | |||
-static int exynos_ehci_atta | |||
-static int exynos_ehci_deta | |||
-static int exynos_ehci_prob | |||
- | |||
-struct exynos_ehci_soft | |||
- device_t dev; | |||
- ehci_softc_t base; | |||
- struct resource *res[4]; | |||
- bus_space_tag_t host_bst; | |||
- bus_space_tag_t sysreg_bst; | |||
- bus_space_handle | |||
- bus_space_handle | |||
- | |||
-}; | |||
- | |||
-static struct resource_spec exynos_ehci_spec | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 1, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 2, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 0, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static device_method_t ehci_methods[] = { | |||
- /* Device interface */ | |||
- DEVMETHOD(device_probe, exynos_ehci_prob | |||
- DEVMETHOD(device_attach, exynos_ehci_atta | |||
- DEVMETHOD(device_detach, exynos_ehci_deta | |||
- DEVMETHOD(device_suspend, bus_generic_susp | |||
- DEVMETHOD(device_resume, bus_generic_resu | |||
- DEVMETHOD(device_shutdown, | |||
- | |||
- /* Bus interface */ | |||
- DEVMETHOD(bus_print_child, | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-/* kobj_class definition */ | |||
-static driver_t ehci_driver = { | |||
- "ehci", | |||
- ehci_methods, | |||
- sizeof(struct exynos_ehci_soft | |||
-}; | |||
- | |||
-static devclass_t ehci_devclass; | |||
- | |||
-DRIVER_MODULE(exynos_ehci, simplebus, ehci_driver, ehci_devclass, 0, 0); | |||
-MODULE_DEPEND(exynos_ehci, usb, 1, 1, 1); | |||
- | |||
-/* | |||
- * Public methods | |||
- */ | |||
-static int | |||
-exynos_ehci_prob | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (ofw_bus_is_compa | |||
- return (ENXIO); | |||
- | |||
- device_set_desc(dev, "Exynos integrated USB controller"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-gpio_ctrl(struct exynos_ehci_soft | |||
-{ | |||
- device_t gpio_dev; | |||
- | |||
- /* Get the GPIO device, we need this to give power to USB */ | |||
- gpio_dev = devclass_get_dev | |||
- if (gpio_dev == NULL) { | |||
- device_printf(esc->dev, "cant find gpio_dev\n"); | |||
- return (1); | |||
- } | |||
- | |||
- if (power) | |||
- GPIO_PIN_SET(gpio_dev, PIN_USB, GPIO_PIN_HIGH); | |||
- else | |||
- GPIO_PIN_SET(gpio_dev, PIN_USB, GPIO_PIN_LOW); | |||
- | |||
- if (dir) | |||
- GPIO_PIN_SETFLAG | |||
- else | |||
- GPIO_PIN_SETFLAG | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-reset_hsic_hub(struct exynos_ehci_soft | |||
-{ | |||
- device_t gpio_dev; | |||
- pcell_t pin; | |||
- | |||
- /* TODO: check that hub is compatible with "smsc,usb3503" */ | |||
- if (!OF_hasprop(hub, "freebsd,reset-gpio")) { | |||
- return (1); | |||
- } | |||
- | |||
- if (OF_getencprop(hub, "freebsd,reset-gpio", &pin, sizeof(pin)) < 0) { | |||
- device_printf(esc->dev, | |||
- "failed to decode reset GPIO pin number for HSIC hub\n"); | |||
- return (1); | |||
- } | |||
- | |||
- /* Get the GPIO device, we need this to give power to USB */ | |||
- gpio_dev = devclass_get_dev | |||
- if (gpio_dev == NULL) { | |||
- device_printf(esc->dev, "Cant find gpio device\n"); | |||
- return (1); | |||
- } | |||
- | |||
- GPIO_PIN_SET(gpio_dev, pin, GPIO_PIN_LOW); | |||
- DELAY(100); | |||
- GPIO_PIN_SET(gpio_dev, pin, GPIO_PIN_HIGH); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-phy_init(struct exynos_ehci_soft | |||
-{ | |||
- int reg; | |||
- phandle_t hub; | |||
- | |||
- gpio_ctrl(esc, GPIO_INPUT, 1); | |||
- | |||
- /* set USB HOST mode */ | |||
- bus_space_write_ | |||
- EXYNOS5_SYSREG_U | |||
- | |||
- /* Power ON phy */ | |||
- usb2_phy_power_o | |||
- | |||
- reg = bus_space_read_4 | |||
- reg &= ~(HOST_CTRL_CLK_MA | |||
- HOST_CTRL_RESET_ | |||
- HOST_CTRL_RESET_ | |||
- HOST_CTRL_SIDDQ | | |||
- HOST_CTRL_SUSPEN | |||
- HOST_CTRL_SLEEP); | |||
- | |||
- reg |= (HOST_CTRL_CLK_24 | |||
- HOST_CTRL_RESET_ | |||
- bus_space_write_ | |||
- | |||
- DELAY(10); | |||
- | |||
- reg = bus_space_read_4 | |||
- reg &= ~(HOST_CTRL_RESET_ | |||
- bus_space_write_ | |||
- | |||
- if ((hub = OF_finddevice("/hsichub")) != -1) { | |||
- reset_hsic_hub(esc, hub); | |||
- } | |||
- | |||
- gpio_ctrl(esc, GPIO_OUTPUT, 1); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos_ehci_atta | |||
-{ | |||
- struct exynos_ehci_soft | |||
- ehci_softc_t *sc; | |||
- bus_space_handle | |||
- int err; | |||
- | |||
- esc = device_get_softc | |||
- esc->dev = dev; | |||
- sc = &esc->base; | |||
- sc->sc_bus.parent = dev; | |||
- sc->sc_bus.devices = sc->sc_devices; | |||
- sc->sc_bus.devices_max = EHCI_MAX_DEVICES | |||
- sc->sc_bus.dma_bits = 32; | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* EHCI registers */ | |||
- sc->sc_io_tag = rman_get_bustag(esc->res[0]); | |||
- bsh = rman_get_bushand | |||
- sc->sc_io_size = rman_get_size(esc->res[0]); | |||
- | |||
- /* EHCI HOST ctrl registers */ | |||
- esc->host_bst = rman_get_bustag(esc->res[1]); | |||
- esc->host_bsh = rman_get_bushand | |||
- | |||
- /* SYSREG */ | |||
- esc->sysreg_bst = rman_get_bustag(esc->res[2]); | |||
- esc->sysreg_bsh = rman_get_bushand | |||
- | |||
- /* get all DMA memory */ | |||
- if (usb_bus_mem_allo | |||
- &ehci_iterate_hw_ | |||
- return (ENXIO); | |||
- | |||
- /* | |||
- * Set handle to USB related registers subregion used by | |||
- * generic EHCI driver. | |||
- */ | |||
- err = bus_space_subreg | |||
- sc->sc_io_size, &sc->sc_io_hdl); | |||
- if (err != 0) | |||
- return (ENXIO); | |||
- | |||
- phy_init(esc); | |||
- | |||
- /* Setup interrupt handler */ | |||
- err = bus_setup_intr(dev, esc->res[3], INTR_TYPE_BIO | INTR_MPSAFE, | |||
- NULL, (driver_intr_t *)ehci_interrupt, sc, | |||
- &sc->sc_intr_hdl); | |||
- if (err) { | |||
- device_printf(dev, "Could not setup irq, " | |||
- "%d\n", err); | |||
- return (1); | |||
- } | |||
- | |||
- /* Add USB device */ | |||
- sc->sc_bus.bdev = device_add_child | |||
- if (!sc->sc_bus.bdev) { | |||
- device_printf(dev, "Could not add USB device\n"); | |||
- err = bus_teardown_int | |||
- sc->sc_intr_hdl); | |||
- if (err) | |||
- device_printf(dev, "Could not tear down irq," | |||
- " %d\n", err); | |||
- return (1); | |||
- } | |||
- device_set_ivars | |||
- | |||
- strlcpy(sc->sc_vendor, "Samsung", sizeof(sc->sc_vendor)); | |||
- | |||
- err = ehci_init(sc); | |||
- if (!err) { | |||
- sc->sc_flags |= EHCI_SCFLG_DONEI | |||
- err = device_probe_and | |||
- } else { | |||
- device_printf(dev, "USB init failed err=%d\n", err); | |||
- | |||
- device_delete_ch | |||
- sc->sc_bus.bdev = NULL; | |||
- | |||
- err = bus_teardown_int | |||
- sc->sc_intr_hdl); | |||
- if (err) | |||
- device_printf(dev, "Could not tear down irq," | |||
- " %d\n", err); | |||
- return (1); | |||
- } | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos_ehci_deta | |||
-{ | |||
- struct exynos_ehci_soft | |||
- ehci_softc_t *sc; | |||
- int err; | |||
- | |||
- esc = device_get_softc | |||
- sc = &esc->base; | |||
- | |||
- if (sc->sc_flags & EHCI_SCFLG_DONEI | |||
- return (0); | |||
- | |||
- /* | |||
- * only call ehci_detach() after ehci_init() | |||
- */ | |||
- if (sc->sc_flags & EHCI_SCFLG_DONEI | |||
- ehci_detach(sc); | |||
- sc->sc_flags &= ~EHCI_SCFLG_DONEI | |||
- } | |||
- | |||
- /* | |||
- * Disable interrupts that might have been switched on in | |||
- * ehci_init. | |||
- */ | |||
- if (sc->sc_io_tag && sc->sc_io_hdl) | |||
- bus_space_write_ | |||
- EHCI_USBINTR, 0); | |||
- | |||
- if (esc->res[3] && sc->sc_intr_hdl) { | |||
- err = bus_teardown_int | |||
- sc->sc_intr_hdl); | |||
- if (err) { | |||
- device_printf(dev, "Could not tear down irq," | |||
- " %d\n", err); | |||
- return (err); | |||
- } | |||
- sc->sc_intr_hdl = NULL; | |||
- } | |||
- | |||
- if (sc->sc_bus.bdev) { | |||
- device_delete_ch | |||
- sc->sc_bus.bdev = NULL; | |||
- } | |||
- | |||
- /* During module unload there are lots of children leftover */ | |||
- device_delete_ch | |||
- | |||
- bus_release_reso | |||
- | |||
- return (0); | |||
-} |
@@ -1,412 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Samsung Exynos 5 Display Controller | |||
- * Chapter 15, Exynos 5 Dual User's Manual Public Rev 1.00 | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
-#include <sys/fbio.h> | |||
-#include <sys/consio.h> | |||
-#include <sys/eventhandler.h> | |||
-#include <sys/gpio.h> | |||
- | |||
-#include <vm/vm.h> | |||
-#include <vm/vm_extern.h> | |||
-#include <vm/vm_kern.h> | |||
-#include <vm/pmap.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <dev/vt/vt.h> | |||
-#include <dev/vt/colors/vt_termcolors.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_common.h> | |||
- | |||
-#include "gpio_if.h" | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include "fb_if.h" | |||
- | |||
-#define FIMDBYPASS_DISP1 | |||
- | |||
-#define VIDCON0 (0x0) | |||
-#define VIDCON0_ENVID (1 << 1) | |||
-#define VIDCON0_ENVID_F (1 << 0) | |||
-#define CLKVAL_F 0xb | |||
-#define CLKVAL_F_OFFSET 6 | |||
- | |||
-#define WINCON0 0x0020 | |||
-#define WINCON1 0x0024 | |||
-#define WINCON2 0x0028 | |||
-#define WINCON3 0x002C | |||
-#define WINCON4 0x0030 | |||
- | |||
-#define ENLOCAL_F (1 << 22) | |||
-#define BPPMODE_F_RGB_16 | |||
-#define BPPMODE_F_OFFSET | |||
-#define ENWIN_F_ENABLE (1 << 0) | |||
-#define HALF_WORD_SWAP_E | |||
- | |||
-#define SHADOWCON 0x0034 | |||
-#define CHANNEL0_EN (1 << 0) | |||
- | |||
-#define VIDOSD0A 0x0040 | |||
-#define VIDOSD0B 0x0044 | |||
-#define VIDOSD0C 0x0048 | |||
- | |||
-#define VIDW00ADD0B0 0x00A0 | |||
-#define VIDW00ADD0B1 0x00A4 | |||
-#define VIDW00ADD0B2 0x20A0 | |||
-#define VIDW00ADD1B0 0x00D0 | |||
-#define VIDW00ADD1B1 0x00D4 | |||
-#define VIDW00ADD1B2 0x20D0 | |||
- | |||
-#define VIDW00ADD2 0x0100 | |||
-#define VIDW01ADD2 0x0104 | |||
-#define VIDW02ADD2 0x0108 | |||
-#define VIDW03ADD2 0x010C | |||
-#define VIDW04ADD2 0x0110 | |||
- | |||
-#define VIDCON1 (0x04) | |||
-#define VIDTCON0 0x0010 | |||
-#define VIDTCON1 0x0014 | |||
-#define VIDTCON2 0x0018 | |||
-#define VIDTCON3 0x001C | |||
- | |||
-#define VIDINTCON0 0x0130 | |||
-#define VIDINTCON1 0x0134 | |||
- | |||
-#define VSYNC_PULSE_WIDT | |||
-#define VSYNC_PULSE_WIDT | |||
-#define V_FRONT_PORCH_VA | |||
-#define V_FRONT_PORCH_OF | |||
-#define V_BACK_PORCH_VAL | |||
-#define V_BACK_PORCH_OFF | |||
- | |||
-#define HSYNC_PULSE_WIDT | |||
-#define HSYNC_PULSE_WIDT | |||
-#define H_FRONT_PORCH_VA | |||
-#define H_FRONT_PORCH_OF | |||
-#define H_BACK_PORCH_VAL | |||
-#define H_BACK_PORCH_OFF | |||
- | |||
-#define HOZVAL_OFFSET 0 | |||
-#define LINEVAL_OFFSET 11 | |||
- | |||
-#define OSD_RIGHTBOTX_F_ | |||
-#define OSD_RIGHTBOTY_F_ | |||
- | |||
-#define DPCLKCON 0x27c | |||
-#define DPCLKCON_EN (1 << 1) | |||
- | |||
-#define DREAD4(_sc, _reg) \ | |||
- bus_space_read_4 | |||
-#define DWRITE4(_sc, _reg, _val) \ | |||
- bus_space_write_ | |||
- | |||
-struct panel_info { | |||
- uint32_t width; | |||
- uint32_t height; | |||
- uint32_t h_back_porch; | |||
- uint32_t h_pulse_width; | |||
- uint32_t h_front_porch; | |||
- uint32_t v_back_porch; | |||
- uint32_t v_pulse_width; | |||
- uint32_t v_front_porch; | |||
- uint32_t clk_div; | |||
- uint32_t backlight_pin; | |||
- uint32_t fixvclk; | |||
- uint32_t ivclk; | |||
- uint32_t clkval_f; | |||
-}; | |||
- | |||
-struct fimd_softc { | |||
- struct resource *res[3]; | |||
- bus_space_tag_t bst; | |||
- bus_space_handle | |||
- bus_space_tag_t bst_disp; | |||
- bus_space_handle | |||
- bus_space_tag_t bst_sysreg; | |||
- bus_space_handle | |||
- | |||
- void *ih; | |||
- device_t dev; | |||
- device_t sc_fbd; /* fbd child */ | |||
- struct fb_info sc_info; | |||
- struct panel_info *panel; | |||
-}; | |||
- | |||
-static struct resource_spec fimd_spec[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Timer registers */ | |||
- { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* FIMD */ | |||
- { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* DISP */ | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static int | |||
-fimd_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (!ofw_bus_is_compa | |||
- return (ENXIO); | |||
- | |||
- device_set_desc(dev, "Samsung Exynos 5 Display Controller"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-get_panel_info(struct fimd_softc *sc, struct panel_info *panel) | |||
-{ | |||
- phandle_t node; | |||
- pcell_t dts_value[3]; | |||
- int len; | |||
- | |||
- if ((node = ofw_bus_get_node | |||
- return (ENXIO); | |||
- | |||
- /* panel size */ | |||
- if ((len = OF_getproplen(node, "panel-size")) <= 0) | |||
- return (ENXIO); | |||
- OF_getencprop(node, "panel-size", dts_value, len); | |||
- panel->width = dts_value[0]; | |||
- panel->height = dts_value[1]; | |||
- | |||
- /* hsync */ | |||
- if ((len = OF_getproplen(node, "panel-hsync")) <= 0) | |||
- return (ENXIO); | |||
- OF_getencprop(node, "panel-hsync", dts_value, len); | |||
- panel->h_back_porch = dts_value[0]; | |||
- panel->h_pulse_width = dts_value[1]; | |||
- panel->h_front_porch = dts_value[2]; | |||
- | |||
- /* vsync */ | |||
- if ((len = OF_getproplen(node, "panel-vsync")) <= 0) | |||
- return (ENXIO); | |||
- OF_getencprop(node, "panel-vsync", dts_value, len); | |||
- panel->v_back_porch = dts_value[0]; | |||
- panel->v_pulse_width = dts_value[1]; | |||
- panel->v_front_porch = dts_value[2]; | |||
- | |||
- /* clk divider */ | |||
- if ((len = OF_getproplen(node, "panel-clk-div")) <= 0) | |||
- return (ENXIO); | |||
- OF_getencprop(node, "panel-clk-div", dts_value, len); | |||
- panel->clk_div = dts_value[0]; | |||
- | |||
- /* backlight pin */ | |||
- if ((len = OF_getproplen(node, "panel-backlight-pin")) <= 0) | |||
- return (ENXIO); | |||
- OF_getencprop(node, "panel-backlight-pin", dts_value, len); | |||
- panel->backlight_pin = dts_value[0]; | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-fimd_init(struct fimd_softc *sc) | |||
-{ | |||
- struct panel_info *panel; | |||
- int reg; | |||
- | |||
- panel = sc->panel; | |||
- | |||
- /* fb_init */ | |||
- reg = panel->ivclk | panel->fixvclk; | |||
- DWRITE4(sc,VIDCON1,reg); | |||
- | |||
- reg = (VIDCON0_ENVID | VIDCON0_ENVID_F); | |||
- reg |= (panel->clkval_f << CLKVAL_F_OFFSET); | |||
- WRITE4(sc,VIDCON0,reg); | |||
- | |||
- reg = (panel->v_pulse_width << VSYNC_PULSE_WIDT | |||
- reg |= (panel->v_front_porch << V_FRONT_PORCH_OF | |||
- reg |= (panel->v_back_porch << V_BACK_PORCH_OFF | |||
- DWRITE4(sc,VIDTCON0,reg); | |||
- | |||
- reg = (panel->h_pulse_width << HSYNC_PULSE_WIDT | |||
- reg |= (panel->h_front_porch << H_FRONT_PORCH_OF | |||
- reg |= (panel->h_back_porch << H_BACK_PORCH_OFF | |||
- DWRITE4(sc,VIDTCON1,reg); | |||
- | |||
- reg = ((panel->width - 1) << HOZVAL_OFFSET); | |||
- reg |= ((panel->height - 1) << LINEVAL_OFFSET); | |||
- DWRITE4(sc,VIDTCON2,reg); | |||
- | |||
- reg = sc->sc_info.fb_pbase; | |||
- WRITE4(sc, VIDW00ADD0B0, reg); | |||
- reg += (sc->sc_info.fb_stride * (sc->sc_info.fb_height + 1)); | |||
- WRITE4(sc, VIDW00ADD1B0, reg); | |||
- WRITE4(sc, VIDW00ADD2, sc->sc_info.fb_stride); | |||
- | |||
- reg = ((panel->width - 1) << OSD_RIGHTBOTX_F_ | |||
- reg |= ((panel->height - 1) << OSD_RIGHTBOTY_F_ | |||
- WRITE4(sc,VIDOSD0B,reg); | |||
- | |||
- reg = panel->width * panel->height; | |||
- WRITE4(sc,VIDOSD0C,reg); | |||
- | |||
- reg = READ4(sc, SHADOWCON); | |||
- reg |= CHANNEL0_EN; | |||
- reg &= ~(1 << 5); /* disable local path for channel0 */ | |||
- WRITE4(sc,SHADOWCON,reg | |||
- | |||
- reg = BPPMODE_F_RGB_16 | |||
- reg |= ENWIN_F_ENABLE | HALF_WORD_SWAP_E | |||
- reg &= ~ENLOCAL_F; /* use DMA */ | |||
- WRITE4(sc,WINCON0,reg); | |||
- | |||
- /* Enable DisplayPort Clk */ | |||
- WRITE4(sc, DPCLKCON, DPCLKCON_EN); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-fimd_attach(device_t dev) | |||
-{ | |||
- struct panel_info panel; | |||
- struct fimd_softc *sc; | |||
- device_t gpio_dev; | |||
- int reg; | |||
- | |||
- sc = device_get_softc | |||
- sc->dev = dev; | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* Memory interface */ | |||
- sc->bst = rman_get_bustag(sc->res[0]); | |||
- sc->bsh = rman_get_bushand | |||
- sc->bst_disp = rman_get_bustag(sc->res[1]); | |||
- sc->bsh_disp = rman_get_bushand | |||
- sc->bst_sysreg = rman_get_bustag(sc->res[2]); | |||
- sc->bsh_sysreg = rman_get_bushand | |||
- | |||
- if (get_panel_info(sc, &panel)) { | |||
- device_printf(dev, "Can't get panel info\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- panel.fixvclk = 0; | |||
- panel.ivclk = 0; | |||
- panel.clkval_f = 2; | |||
- | |||
- sc->panel = &panel; | |||
- | |||
- /* Get the GPIO device, we need this to give power to USB */ | |||
- gpio_dev = devclass_get_dev | |||
- if (gpio_dev == NULL) { | |||
- /* TODO */ | |||
- } | |||
- | |||
- reg = bus_space_read_4 | |||
- reg |= FIMDBYPASS_DISP1 | |||
- bus_space_write_ | |||
- | |||
- sc->sc_info.fb_width = panel.width; | |||
- sc->sc_info.fb_height = panel.height; | |||
- sc->sc_info.fb_stride = sc->sc_info.fb_width * 2; | |||
- sc->sc_info.fb_bpp = sc->sc_info.fb_depth = 16; | |||
- sc->sc_info.fb_size = sc->sc_info.fb_height * sc->sc_info.fb_stride; | |||
- sc->sc_info.fb_vbase = (intptr_t)kmem_alloc_conti | |||
- M_ZERO, 0, ~0, PAGE_SIZE, 0, VM_MEMATTR_UNCAC | |||
- sc->sc_info.fb_pbase = (intptr_t)vtophys(sc->sc_info.fb_vbase); | |||
- | |||
-#if 0 | |||
- printf("%dx%d [%d]\n", sc->sc_info.fb_width, sc->sc_info.fb_height, | |||
- sc->sc_info.fb_stride); | |||
- printf("pbase == 0x%08x\n", sc->sc_info.fb_pbase); | |||
-#endif | |||
- | |||
- memset((int8_t *)sc->sc_info.fb_vbase, 0x0, sc->sc_info.fb_size); | |||
- | |||
- fimd_init(sc); | |||
- | |||
- sc->sc_info.fb_name = device_get_nameu | |||
- | |||
- /* Ask newbus to attach framebuffer device to me. */ | |||
- sc->sc_fbd = device_add_child | |||
- if (sc->sc_fbd == NULL) | |||
- device_printf(dev, "Can't attach fbd device\n"); | |||
- | |||
- if (device_probe_and | |||
- device_printf(sc->dev, "Failed to attach fbd device\n"); | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static struct fb_info * | |||
-fimd_fb_getinfo(device_t dev) | |||
-{ | |||
- struct fimd_softc *sc = device_get_softc | |||
- | |||
- return (&sc->sc_info); | |||
-} | |||
- | |||
-static device_method_t fimd_methods[] = { | |||
- DEVMETHOD(device_probe, fimd_probe), | |||
- DEVMETHOD(device_attach, fimd_attach), | |||
- | |||
- /* Framebuffer service methods */ | |||
- DEVMETHOD(fb_getinfo, fimd_fb_getinfo), | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t fimd_driver = { | |||
- "fb", | |||
- fimd_methods, | |||
- sizeof(struct fimd_softc), | |||
-}; | |||
- | |||
-static devclass_t fimd_devclass; | |||
- | |||
-DRIVER_MODULE(fb, simplebus, fimd_driver, fimd_devclass, 0, 0); |
@@ -1,479 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Samsung Exynos 5 Inter-Integrated Circuit (I2C) | |||
- * Chapter 13, Exynos 5 Dual User's Manual Public Rev 1.00 | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
- | |||
-#include <dev/iicbus/iiconf.h> | |||
-#include <dev/iicbus/iicbus.h> | |||
- | |||
-#include "iicbus_if.h" | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_common.h> | |||
- | |||
-#define I2CCON 0x00 /* Control register */ | |||
-#define ACKGEN (1 << 7) /* Acknowledge Enable */ | |||
-/* | |||
- * Source Clock of I2C-bus Transmit Clock Prescaler | |||
- * | |||
- * 0 = I2CCLK = fPCLK/16 | |||
- * 1 = I2CCLK = fPCLK/512 | |||
- */ | |||
-#define I2CCLK (1 << 6) | |||
-#define IRQ_EN (1 << 5) /* Tx/Rx Interrupt Enable/Disable */ | |||
-#define IPEND (1 << 4) /* Tx/Rx Interrupt Pending Flag */ | |||
-#define CLKVAL_M 0xf /* Transmit Clock Prescaler Mask */ | |||
-#define CLKVAL_S 0 | |||
-#define I2CSTAT 0x04 /* Control/status register */ | |||
-#define I2CMODE_M 0x3 /* Master/Slave Tx/Rx Mode Select */ | |||
-#define I2CMODE_S 6 | |||
-#define I2CMODE_SR 0x0 /* Slave Receive Mode */ | |||
-#define I2CMODE_ST 0x1 /* Slave Transmit Mode */ | |||
-#define I2CMODE_MR 0x2 /* Master Receive Mode */ | |||
-#define I2CMODE_MT 0x3 /* Master Transmit Mode */ | |||
-#define I2CSTAT_BSY (1 << 5) /* Busy Signal Status bit */ | |||
-#define I2C_START_STOP (1 << 5) /* Busy Signal Status bit */ | |||
-#define RXTX_EN (1 << 4) /* Data Output Enable/Disable */ | |||
-#define ARBST (1 << 3) /* Arbitration status flag */ | |||
-#define ADDAS (1 << 2) /* Address-as-slave Status Flag */ | |||
-#define ADDZERO (1 << 1) /* Address Zero Status Flag */ | |||
-#define ACKRECVD (1 << 0) /* Last-received Bit Status Flag */ | |||
-#define I2CADD 0x08 /* Address register */ | |||
-#define I2CDS 0x0C /* Transmit/receive data shift */ | |||
-#define I2CLC 0x10 /* Multi-master line control */ | |||
-#define FILTER_EN (1 << 2) /* Filter Enable bit */ | |||
-#define SDAOUT_DELAY_M 0x3 /* SDA Line Delay Length */ | |||
-#define SDAOUT_DELAY_S 0 | |||
- | |||
-#ifdef DEBUG | |||
-#define DPRINTF(fmt, args...) \ | |||
- printf(fmt, ##args) | |||
-#else | |||
-#define DPRINTF(fmt, args...) | |||
-#endif | |||
- | |||
-static int i2c_start(device_t, u_char, int); | |||
-static int i2c_stop(device_t); | |||
-static int i2c_reset(device_t, u_char, u_char, u_char *); | |||
-static int i2c_read(device_t, char *, int, int *, int, int); | |||
-static int i2c_write(device_t, const char *, int, int *, int); | |||
- | |||
-struct i2c_softc { | |||
- struct resource *res[2]; | |||
- bus_space_tag_t bst; | |||
- bus_space_handle | |||
- device_t dev; | |||
- device_t iicbus; | |||
- struct mtx mutex; | |||
- void *ih; | |||
- int intr; | |||
-}; | |||
- | |||
-static struct resource_spec i2c_spec[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 0, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static int | |||
-i2c_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (!ofw_bus_is_compa | |||
- return (ENXIO); | |||
- | |||
- device_set_desc(dev, "Samsung Exynos 5 I2C controller"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-clear_ipend(struct i2c_softc *sc) | |||
-{ | |||
- int reg; | |||
- | |||
- reg = READ1(sc, I2CCON); | |||
- reg &= ~(IPEND); | |||
- WRITE1(sc, I2CCON, reg); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-i2c_attach(device_t dev) | |||
-{ | |||
- struct i2c_softc *sc; | |||
- int reg; | |||
- | |||
- sc = device_get_softc | |||
- sc->dev = dev; | |||
- | |||
- mtx_init(&sc->mutex, device_get_nameu | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* Memory interface */ | |||
- sc->bst = rman_get_bustag(sc->res[0]); | |||
- sc->bsh = rman_get_bushand | |||
- | |||
- sc->iicbus = device_add_child | |||
- if (sc->iicbus == NULL) { | |||
- device_printf(dev, "could not add iicbus child"); | |||
- mtx_destroy(&sc->mutex); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- WRITE1(sc, I2CSTAT, 0); | |||
- WRITE1(sc, I2CADD, 0x00); | |||
- | |||
- /* Mode */ | |||
- reg = (RXTX_EN); | |||
- reg |= (I2CMODE_MT << I2CMODE_S); | |||
- WRITE1(sc, I2CSTAT, reg); | |||
- | |||
- bus_generic_atta | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-wait_for_iif(struct i2c_softc *sc) | |||
-{ | |||
- int retry; | |||
- int reg; | |||
- | |||
- retry = 1000; | |||
- while (retry --) { | |||
- reg = READ1(sc, I2CCON); | |||
- if (reg & IPEND) { | |||
- return (IIC_NOERR); | |||
- } | |||
- DELAY(50); | |||
- } | |||
- | |||
- return (IIC_ETIMEOUT); | |||
-} | |||
- | |||
-static int | |||
-wait_for_nibb(struct i2c_softc *sc) | |||
-{ | |||
- int retry; | |||
- | |||
- retry = 1000; | |||
- while (retry --) { | |||
- if ((READ1(sc, I2CSTAT) & I2CSTAT_BSY) == 0) | |||
- return (IIC_NOERR); | |||
- DELAY(10); | |||
- } | |||
- | |||
- return (IIC_ETIMEOUT); | |||
-} | |||
- | |||
-static int | |||
-is_ack(struct i2c_softc *sc) | |||
-{ | |||
- int stat; | |||
- | |||
- stat = READ1(sc, I2CSTAT); | |||
- if (!(stat & 1)) { | |||
- /* ACK received */ | |||
- return (1); | |||
- } | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-i2c_start(device_t dev, u_char slave, int timeout) | |||
-{ | |||
- struct i2c_softc *sc; | |||
- int error; | |||
- int reg; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- DPRINTF("i2c start\n"); | |||
- | |||
- mtx_lock(&sc->mutex); | |||
- | |||
-#if 0 | |||
- DPRINTF("I2CCON == 0x%08x\n", READ1(sc, I2CCON)); | |||
- DPRINTF("I2CSTAT == 0x%08x\n", READ1(sc, I2CSTAT)); | |||
-#endif | |||
- | |||
- if (slave & 1) { | |||
- slave &= ~(1); | |||
- slave <<= 1; | |||
- slave |= 1; | |||
- } else { | |||
- slave <<= 1; | |||
- } | |||
- | |||
- error = wait_for_nibb(sc); | |||
- if (error) { | |||
- mtx_unlock(&sc->mutex); | |||
- DPRINTF("cant i2c start: IIC_EBUSERR\n"); | |||
- return (IIC_EBUSERR); | |||
- } | |||
- | |||
- reg = READ1(sc, I2CCON); | |||
- reg |= (IRQ_EN | ACKGEN); | |||
- WRITE1(sc, I2CCON, reg); | |||
- | |||
- WRITE1(sc, I2CDS, slave); | |||
- DELAY(50); | |||
- | |||
- reg = (RXTX_EN); | |||
- reg |= I2C_START_STOP; | |||
- reg |= (I2CMODE_MT << I2CMODE_S); | |||
- WRITE1(sc, I2CSTAT, reg); | |||
- | |||
- error = wait_for_iif(sc); | |||
- if (error) { | |||
- DPRINTF("cant i2c start: iif error\n"); | |||
- | |||
- mtx_unlock(&sc->mutex); | |||
- return (error); | |||
- } | |||
- | |||
- if (!is_ack(sc)) { | |||
- DPRINTF("cant i2c start: no ack\n"); | |||
- | |||
- mtx_unlock(&sc->mutex); | |||
- return (IIC_ENOACK); | |||
- } | |||
- | |||
- mtx_unlock(&sc->mutex); | |||
- return (IIC_NOERR); | |||
-} | |||
- | |||
-static int | |||
-i2c_stop(device_t dev) | |||
-{ | |||
- struct i2c_softc *sc; | |||
- int reg; | |||
- int error; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- DPRINTF("i2c stop\n"); | |||
- | |||
- mtx_lock(&sc->mutex); | |||
- | |||
- reg = READ1(sc, I2CSTAT); | |||
- int mode = (reg >> I2CMODE_S) & I2CMODE_M; | |||
- | |||
- reg = (RXTX_EN); | |||
- reg |= (mode << I2CMODE_S); | |||
- WRITE1(sc, I2CSTAT, reg); | |||
- | |||
- clear_ipend(sc); | |||
- | |||
- error = wait_for_nibb(sc); | |||
- if (error) { | |||
- DPRINTF("cant i2c stop: nibb error\n"); | |||
- return (error); | |||
- } | |||
- | |||
- mtx_unlock(&sc->mutex); | |||
- return (IIC_NOERR); | |||
-} | |||
- | |||
-static int | |||
-i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) | |||
-{ | |||
- struct i2c_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- DPRINTF("i2c reset\n"); | |||
- | |||
- mtx_lock(&sc->mutex); | |||
- | |||
- /* TODO */ | |||
- | |||
- mtx_unlock(&sc->mutex); | |||
- | |||
- return (IIC_NOERR); | |||
-} | |||
- | |||
-static int | |||
-i2c_read(device_t dev, char *buf, int len, | |||
- int *read, int last, int delay) | |||
-{ | |||
- struct i2c_softc *sc; | |||
- int error; | |||
- int reg; | |||
- uint8_t d; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- DPRINTF("i2c read\n"); | |||
- | |||
- reg = (RXTX_EN); | |||
- reg |= (I2CMODE_MR << I2CMODE_S); | |||
- reg |= I2C_START_STOP; | |||
- WRITE1(sc, I2CSTAT, reg); | |||
- | |||
- *read = 0; | |||
- mtx_lock(&sc->mutex); | |||
- | |||
- /* dummy read */ | |||
- clear_ipend(sc); | |||
- error = wait_for_iif(sc); | |||
- if (error) { | |||
- DPRINTF("cant i2c read: iif error\n"); | |||
- mtx_unlock(&sc->mutex); | |||
- return (error); | |||
- } | |||
- READ1(sc, I2CDS); | |||
- | |||
- DPRINTF("Read "); | |||
- while (*read < len) { | |||
- /* Do not ack last read */ | |||
- if (*read == (len - 1)) { | |||
- reg = READ1(sc, I2CCON); | |||
- reg &= ~(ACKGEN); | |||
- WRITE1(sc, I2CCON, reg); | |||
- } | |||
- | |||
- clear_ipend(sc); | |||
- | |||
- error = wait_for_iif(sc); | |||
- if (error) { | |||
- DPRINTF("cant i2c read: iif error\n"); | |||
- mtx_unlock(&sc->mutex); | |||
- return (error); | |||
- } | |||
- | |||
- d = READ1(sc, I2CDS); | |||
- DPRINTF("0x%02x ", d); | |||
- *buf++ = d; | |||
- (*read)++; | |||
- } | |||
- DPRINTF("\n"); | |||
- | |||
- mtx_unlock(&sc->mutex); | |||
- return (IIC_NOERR); | |||
-} | |||
- | |||
-static int | |||
-i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout) | |||
-{ | |||
- struct i2c_softc *sc; | |||
- int error; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- DPRINTF("i2c write\n"); | |||
- | |||
- *sent = 0; | |||
- | |||
- mtx_lock(&sc->mutex); | |||
- | |||
- DPRINTF("writing "); | |||
- while (*sent < len) { | |||
- uint8_t d = *buf++; | |||
- DPRINTF("0x%02x ", d); | |||
- | |||
- WRITE1(sc, I2CDS, d); | |||
- DELAY(50); | |||
- | |||
- clear_ipend(sc); | |||
- | |||
- error = wait_for_iif(sc); | |||
- if (error) { | |||
- DPRINTF("cant i2c write: iif error\n"); | |||
- mtx_unlock(&sc->mutex); | |||
- return (error); | |||
- } | |||
- | |||
- if (!is_ack(sc)) { | |||
- DPRINTF("cant i2c write: no ack\n"); | |||
- mtx_unlock(&sc->mutex); | |||
- return (IIC_ENOACK); | |||
- } | |||
- | |||
- (*sent)++; | |||
- } | |||
- DPRINTF("\n"); | |||
- | |||
- mtx_unlock(&sc->mutex); | |||
- return (IIC_NOERR); | |||
-} | |||
- | |||
-static device_method_t i2c_methods[] = { | |||
- DEVMETHOD(device_probe, i2c_probe), | |||
- DEVMETHOD(device_attach, i2c_attach), | |||
- | |||
- DEVMETHOD(iicbus_callback, | |||
- DEVMETHOD(iicbus_start, i2c_start), | |||
- DEVMETHOD(iicbus_stop, i2c_stop), | |||
- DEVMETHOD(iicbus_reset, i2c_reset), | |||
- DEVMETHOD(iicbus_read, i2c_read), | |||
- DEVMETHOD(iicbus_write, i2c_write), | |||
- DEVMETHOD(iicbus_transfer, | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t i2c_driver = { | |||
- "i2c", | |||
- i2c_methods, | |||
- sizeof(struct i2c_softc), | |||
-}; | |||
- | |||
-static devclass_t i2c_devclass; | |||
- | |||
-DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0); | |||
-DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, |
@@ -1,96 +0,0 @@ | |||
-/*- | |||
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||
- * | |||
- * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-#include "opt_platform.h" | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/devmap.h> | |||
- | |||
-#include <vm/vm.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
- | |||
-#include <machine/armreg.h> | |||
-#include <machine/bus.h> | |||
-#include <machine/fdt.h> | |||
-#include <machine/machdep.h> | |||
-#include <machine/platform.h> | |||
-#include <machine/platformvar.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_mp.h> | |||
- | |||
-#include "platform_if.h" | |||
- | |||
-static platform_devmap_ | |||
-static platform_cpu_res | |||
- | |||
-static int | |||
-exynos5_devmap_i | |||
-{ | |||
- | |||
- /* CHIP ID */ | |||
- devmap_add_entry | |||
- | |||
- /* UART */ | |||
- devmap_add_entry | |||
- | |||
- /* DWMMC */ | |||
- devmap_add_entry | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static void | |||
-exynos5_cpu_rese | |||
-{ | |||
- bus_space_handle | |||
- | |||
- bus_space_map(fdtbus_bs_tag, 0x10040400, 0x1000, 0, &bsh); | |||
- bus_space_write_ | |||
- | |||
- while (1); | |||
-} | |||
- | |||
-static platform_method_ | |||
- PLATFORMMETHOD(platform_devmap_ | |||
- PLATFORMMETHOD(platform_cpu_res | |||
- | |||
-#ifdef SMP | |||
- PLATFORMMETHOD(platform_mp_star | |||
- PLATFORMMETHOD(platform_mp_setm | |||
-#endif | |||
- | |||
- PLATFORMMETHOD_E | |||
-}; | |||
- | |||
-FDT_PLATFORM_DEF |
@@ -1,137 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * This module just enables Exynos MCT, so ARMv7 Generic Timer will works | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
- | |||
-#define MCT_CTRL_START (1 << 8) | |||
-#define MCT_CTRL (0x240) | |||
-#define MCT_WRITE_STAT (0x24C) | |||
- | |||
-struct arm_tmr_softc { | |||
- struct resource *tmr_res[1]; | |||
- bus_space_tag_t bst; | |||
- bus_space_handle | |||
-}; | |||
- | |||
-static struct resource_spec arm_tmr_spec[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Timer registers */ | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static int | |||
-arm_tmr_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (!ofw_bus_is_compa | |||
- return (ENXIO); | |||
- | |||
- device_set_desc(dev, "Exynos MPCore Timer"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-arm_tmr_attach(device_t dev) | |||
-{ | |||
- struct arm_tmr_softc *sc; | |||
- int reg, i; | |||
- int mask; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* Timer interface */ | |||
- sc->bst = rman_get_bustag(sc->tmr_res[0]); | |||
- sc->bsh = rman_get_bushand | |||
- | |||
- reg = bus_space_read_4 | |||
- reg |= MCT_CTRL_START; | |||
- bus_space_write_ | |||
- | |||
- mask = (1 << 16); | |||
- | |||
- /* Wait 10 times until written value is applied */ | |||
- for (i = 0; i < 10; i++) { | |||
- reg = bus_space_read_4 | |||
- if (reg & mask) { | |||
- bus_space_write_ | |||
- MCT_WRITE_STAT, mask); | |||
- return (0); | |||
- } | |||
- cpufunc_nullop(); | |||
- } | |||
- | |||
- /* NOTREACHED */ | |||
- | |||
- panic("Can't enable timer\n"); | |||
-} | |||
- | |||
-static device_method_t arm_tmr_methods[] = { | |||
- DEVMETHOD(device_probe, arm_tmr_probe), | |||
- DEVMETHOD(device_attach, arm_tmr_attach), | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t arm_tmr_driver = { | |||
- "mct", | |||
- arm_tmr_methods, | |||
- sizeof(struct arm_tmr_softc), | |||
-}; | |||
- | |||
-static devclass_t arm_tmr_devclass | |||
- | |||
-DRIVER_MODULE(mct, simplebus, arm_tmr_driver, arm_tmr_devclass |
@@ -1,136 +0,0 @@ | |||
-/*- | |||
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||
- * | |||
- * Copyright (c) 2013-2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/lock.h> | |||
-#include <sys/mutex.h> | |||
-#include <sys/smp.h> | |||
- | |||
-#include <vm/vm.h> | |||
-#include <vm/pmap.h> | |||
- | |||
-#include <machine/cpu.h> | |||
-#include <machine/smp.h> | |||
-#include <machine/fdt.h> | |||
-#include <machine/intr.h> | |||
-#include <machine/platformvar.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_mp.h> | |||
- | |||
-#define EXYNOS_CHIPID 0x10000000 | |||
- | |||
-#define EXYNOS5250_SOC_I | |||
-#define EXYNOS5420_SOC_I | |||
-#define EXYNOS5_SOC_ID_M | |||
- | |||
-#define EXYNOS_SYSRAM 0x02020000 | |||
-#define EXYNOS5420_SYSRA | |||
- | |||
-#define EXYNOS_PMU_BASE 0x10040000 | |||
-#define CORE_CONFIG(n) (0x2000 + (0x80 * (n))) | |||
-#define CORE_STATUS(n) (CORE_CONFIG(n) + 0x4) | |||
-#define CORE_PWR_EN 0x3 | |||
- | |||
-static int | |||
-exynos_get_soc_i | |||
-{ | |||
- bus_addr_t chipid; | |||
- int reg; | |||
- | |||
- if (bus_space_map(fdtbus_bs_tag, EXYNOS_CHIPID, | |||
- 0x1000, 0, &chipid) != 0) | |||
- panic("Couldn't map chipid\n"); | |||
- reg = bus_space_read_4 | |||
- bus_space_unmap(fdtbus_bs_tag, chipid, 0x1000); | |||
- | |||
- return (reg & EXYNOS5_SOC_ID_M | |||
-} | |||
- | |||
-void | |||
-exynos5_mp_setma | |||
-{ | |||
- | |||
- if (exynos_get_soc_i | |||
- mp_ncpus = 4; | |||
- else | |||
- mp_ncpus = 2; | |||
- | |||
- mp_maxid = mp_ncpus - 1; | |||
-} | |||
- | |||
-void | |||
-exynos5_mp_start | |||
-{ | |||
- bus_addr_t sysram, pmu; | |||
- int err, i, j; | |||
- int status; | |||
- int reg; | |||
- | |||
- err = bus_space_map(fdtbus_bs_tag, EXYNOS_PMU_BASE, | |||
- if (err != 0) | |||
- panic("Couldn't map pmu\n"); | |||
- | |||
- if (exynos_get_soc_i | |||
- reg = EXYNOS5420_SYSRA | |||
- else | |||
- reg = EXYNOS_SYSRAM; | |||
- | |||
- err = bus_space_map(fdtbus_bs_tag, reg, 0x100, 0, &sysram); | |||
- if (err != 0) | |||
- panic("Couldn't map sysram\n"); | |||
- | |||
- /* Give power to CPUs */ | |||
- for (i = 1; i < mp_ncpus; i++) { | |||
- bus_space_write_ | |||
- CORE_PWR_EN); | |||
- | |||
- for (j = 10; j >= 0; j--) { | |||
- status = bus_space_read_4 | |||
- CORE_STATUS(i)); | |||
- if ((status & CORE_PWR_EN) == CORE_PWR_EN) | |||
- break; | |||
- DELAY(10); | |||
- if (j == 0) | |||
- printf("Can't power on CPU%d\n", i); | |||
- } | |||
- } | |||
- | |||
- bus_space_write_ | |||
- pmap_kextract((vm_offset_t)mpentry)); | |||
- | |||
- dcache_wbinv_poc | |||
- | |||
- dsb(); | |||
- sev(); | |||
- bus_space_unmap(fdtbus_bs_tag, sysram, 0x100); | |||
- bus_space_unmap(fdtbus_bs_tag, pmu, 0x20000); | |||
-} |
@@ -1,34 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2017 Andrew Turner <andrew@FreeBSD.org> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |||
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |||
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
- * | |||
- * $FreeBSD$ | |||
- */ | |||
- | |||
-#ifndef _EXYNOS5_MP_H_ | |||
-#define _EXYNOS5_MP_H_ | |||
- | |||
-void exynos5_mp_setma | |||
-void exynos5_mp_start | |||
- | |||
-#endif /* _EXYNOS5_MP_H_ */ |
@@ -1,854 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Samsung Exynos 5 Pad Control | |||
- * Chapter 4, Exynos 5 Dual User's Manual Public Rev 1.00 | |||
- */ | |||
-#ifdef USB_GLOBAL_INCLU | |||
-#include USB_GLOBAL_INCLU | |||
-#else | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
-#include <sys/mutex.h> | |||
-#include <sys/gpio.h> | |||
- | |||
-#include <dev/gpio/gpiobusvar.h> | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include "gpio_if.h" | |||
-#endif | |||
- | |||
-#include <arm/samsung/exynos/exynos5_combiner | |||
-#include <arm/samsung/exynos/exynos5_pad.h> | |||
- | |||
-#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) | |||
-#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) | |||
- | |||
-#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) | |||
- | |||
-#define MAX_PORTS 5 | |||
-#define MAX_NGPIO 253 | |||
- | |||
-#define N_EXT_INTS 16 | |||
- | |||
-#define EXYNOS5250 1 | |||
-#define EXYNOS5420 2 | |||
- | |||
-#define PIN_IN 0 | |||
-#define PIN_OUT 1 | |||
- | |||
-#define READ4(_sc, _port, _reg) \ | |||
- bus_space_read_4 | |||
-#define WRITE4(_sc, _port, _reg, _val) \ | |||
- bus_space_write_ | |||
- | |||
-/* | |||
- * GPIO interface | |||
- */ | |||
-static device_t pad_get_bus(device_t); | |||
-static int pad_pin_max(device_t, int *); | |||
-static int pad_pin_getcaps(device_t, uint32_t, uint32_t *); | |||
-static int pad_pin_getname(device_t, uint32_t, char *); | |||
-static int pad_pin_getflags | |||
-static int pad_pin_setflags | |||
-static int pad_pin_set(device_t, uint32_t, unsigned int); | |||
-static int pad_pin_get(device_t, uint32_t, unsigned int *); | |||
-static int pad_pin_toggle(device_t, uint32_t pin); | |||
- | |||
-struct gpio_bank { | |||
- char *name; | |||
- uint32_t port; | |||
- uint32_t con; | |||
- uint32_t ngpio; | |||
- uint32_t ext_con; | |||
- uint32_t ext_flt_con; | |||
- uint32_t mask; | |||
- uint32_t pend; | |||
-}; | |||
- | |||
-struct pad_softc { | |||
- struct resource *res[MAX_PORTS * 2]; | |||
- bus_space_tag_t bst[MAX_PORTS]; | |||
- bus_space_handle | |||
- struct mtx sc_mtx; | |||
- int gpio_npins; | |||
- struct gpio_pin gpio_pins[MAX_NGPIO]; | |||
- void *gpio_ih[MAX_PORTS]; | |||
- device_t dev; | |||
- device_t busdev; | |||
- int model; | |||
- struct resource_spec *pad_spec; | |||
- struct gpio_bank *gpio_map; | |||
- struct interrupt_entry *interrupt_table; | |||
- int nports; | |||
-}; | |||
- | |||
-struct pad_softc *gpio_sc; | |||
- | |||
-static struct resource_spec pad_spec_5250[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 1, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 2, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 3, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 0, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 1, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 2, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 3, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static struct resource_spec pad_spec_5420[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 1, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 2, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 3, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 4, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 0, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 1, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 2, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 3, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 4, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static struct ofw_compat_data compat_data[] = { | |||
- {"samsung,exynos54 | |||
- {"samsung,exynos52 | |||
- {NULL, 0} | |||
-}; | |||
- | |||
-struct pad_intr { | |||
- uint32_t enabled; | |||
- void (*ih) (void *); | |||
- void *ih_user; | |||
-}; | |||
- | |||
-static struct pad_intr intr_map[MAX_NGPIO]; | |||
- | |||
-struct interrupt_entry { | |||
- int gpio_number; | |||
- char *combiner_source_ | |||
-}; | |||
- | |||
-struct interrupt_entry interrupt_table_ | |||
- { 147, "EINT[15]" }, | |||
- { 146, "EINT[14]" }, | |||
- { 145, "EINT[13]" }, | |||
- { 144, "EINT[12]" }, | |||
- { 143, "EINT[11]" }, | |||
- { 142, "EINT[10]" }, | |||
- { 141, "EINT[9]" }, | |||
- { 140, "EINT[8]" }, | |||
- { 139, "EINT[7]" }, | |||
- { 138, "EINT[6]" }, | |||
- { 137, "EINT[5]" }, | |||
- { 136, "EINT[4]" }, | |||
- { 135, "EINT[3]" }, | |||
- { 134, "EINT[2]" }, | |||
- { 133, "EINT[1]" }, | |||
- { 132, "EINT[0]" }, | |||
-}; | |||
- | |||
-struct interrupt_entry interrupt_table_ | |||
- { 23, "EINT[15]" }, | |||
- { 22, "EINT[14]" }, | |||
- { 21, "EINT[13]" }, | |||
- { 20, "EINT[12]" }, | |||
- { 19, "EINT[11]" }, | |||
- { 18, "EINT[10]" }, | |||
- { 17, "EINT[9]" }, | |||
- { 16, "EINT[8]" }, | |||
- { 15, "EINT[7]" }, | |||
- { 14, "EINT[6]" }, | |||
- { 13, "EINT[5]" }, | |||
- { 12, "EINT[4]" }, | |||
- { 11, "EINT[3]" }, | |||
- { 10, "EINT[2]" }, | |||
- { 9, "EINT[1]" }, | |||
- { 8, "EINT[0]" }, | |||
-}; | |||
- | |||
-/* | |||
- * 253 multi-functional input/output ports | |||
- */ | |||
- | |||
-static struct gpio_bank gpio_map_5250[] = { | |||
- /* first 132 gpio */ | |||
- { "gpa0", 0, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 }, | |||
- { "gpa1", 0, 0x020, 6, 0x704, 0x808, 0x904, 0xA04 }, | |||
- { "gpa2", 0, 0x040, 8, 0x708, 0x810, 0x908, 0xA08 }, | |||
- { "gpb0", 0, 0x060, 5, 0x70C, 0x818, 0x90C, 0xA0C }, | |||
- { "gpb1", 0, 0x080, 5, 0x710, 0x820, 0x910, 0xA10 }, | |||
- { "gpb2", 0, 0x0A0, 4, 0x714, 0x828, 0x914, 0xA14 }, | |||
- { "gpb3", 0, 0x0C0, 4, 0x718, 0x830, 0x918, 0xA18 }, | |||
- { "gpc0", 0, 0x0E0, 7, 0x71C, 0x838, 0x91C, 0xA1C }, | |||
- { "gpc1", 0, 0x100, 4, 0x720, 0x840, 0x920, 0xA20 }, | |||
- { "gpc2", 0, 0x120, 7, 0x724, 0x848, 0x924, 0xA24 }, | |||
- { "gpc3", 0, 0x140, 7, 0x728, 0x850, 0x928, 0xA28 }, | |||
- { "gpd0", 0, 0x160, 4, 0x72C, 0x858, 0x92C, 0xA2C }, | |||
- { "gpd1", 0, 0x180, 8, 0x730, 0x860, 0x930, 0xA30 }, | |||
- { "gpy0", 0, 0x1A0, 6, 0, 0, 0, 0 }, | |||
- { "gpy1", 0, 0x1C0, 4, 0, 0, 0, 0 }, | |||
- { "gpy2", 0, 0x1E0, 6, 0, 0, 0, 0 }, | |||
- { "gpy3", 0, 0x200, 8, 0, 0, 0, 0 }, | |||
- { "gpy4", 0, 0x220, 8, 0, 0, 0, 0 }, | |||
- { "gpy5", 0, 0x240, 8, 0, 0, 0, 0 }, | |||
- { "gpy6", 0, 0x260, 8, 0, 0, 0, 0 }, | |||
- { "gpc4", 0, 0x2E0, 7, 0x734, 0x868, 0x934, 0xA34 }, | |||
- | |||
- /* next 32 */ | |||
- { "gpx0", 0, 0xC00, 8, 0xE00, 0xE80, 0xF00, 0xF40 }, | |||
- { "gpx1", 0, 0xC20, 8, 0xE04, 0xE88, 0xF04, 0xF44 }, | |||
- { "gpx2", 0, 0xC40, 8, 0xE08, 0xE90, 0xF08, 0xF48 }, | |||
- { "gpx3", 0, 0xC60, 8, 0xE0C, 0xE98, 0xF0C, 0xF4C }, | |||
- | |||
- { "gpe0", 1, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 }, | |||
- { "gpe1", 1, 0x020, 2, 0x704, 0x808, 0x904, 0xA04 }, | |||
- { "gpf0", 1, 0x040, 4, 0x708, 0x810, 0x908, 0xA08 }, | |||
- { "gpf1", 1, 0x060, 4, 0x70C, 0x818, 0x90C, 0xA0C }, | |||
- { "gpg0", 1, 0x080, 8, 0x710, 0x820, 0x910, 0xA10 }, | |||
- { "gpg1", 1, 0x0A0, 8, 0x714, 0x828, 0x914, 0xA14 }, | |||
- { "gpg2", 1, 0x0C0, 2, 0x718, 0x830, 0x918, 0xA18 }, | |||
- { "gph0", 1, 0x0E0, 4, 0x71C, 0x838, 0x91C, 0xA1C }, | |||
- { "gph1", 1, 0x100, 8, 0x720, 0x840, 0x920, 0xA20 }, | |||
- | |||
- { "gpv0", 2, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 }, | |||
- { "gpv1", 2, 0x020, 8, 0x704, 0x808, 0x904, 0xA04 }, | |||
- { "gpv2", 2, 0x060, 8, 0x708, 0x810, 0x908, 0xA08 }, | |||
- { "gpv3", 2, 0x080, 8, 0x70C, 0x818, 0x90C, 0xA0C }, | |||
- { "gpv4", 2, 0x0C0, 2, 0x710, 0x820, 0x910, 0xA10 }, | |||
- | |||
- { "gpz", 3, 0x000, 7, 0x700, 0x800, 0x900, 0xA00 }, | |||
- | |||
- { NULL, -1, -1, -1, -1, -1, -1, -1 }, | |||
-}; | |||
- | |||
-static struct gpio_bank gpio_map_5420[] = { | |||
- /* First 40 */ | |||
- { "gpy7", 0, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 }, | |||
- { "gpx0", 0, 0xC00, 8, 0x704, 0xE80, 0xF00, 0xF40 }, | |||
- { "gpx1", 0, 0xC20, 8, 0x708, 0xE88, 0xF04, 0xF44 }, | |||
- { "gpx2", 0, 0xC40, 8, 0x70C, 0xE90, 0xF08, 0xF48 }, | |||
- { "gpx3", 0, 0xC60, 8, 0x710, 0xE98, 0xF0C, 0xF4C }, | |||
- | |||
- /* Next 85 */ | |||
- { "gpc0", 1, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 }, | |||
- { "gpc1", 1, 0x020, 8, 0x704, 0x808, 0x904, 0xA04 }, | |||
- { "gpc2", 1, 0x040, 7, 0x708, 0x810, 0x908, 0xA08 }, | |||
- { "gpc3", 1, 0x060, 4, 0x70C, 0x818, 0x90C, 0xA0C }, | |||
- { "gpc4", 1, 0x080, 2, 0x710, 0x820, 0x910, 0xA10 }, | |||
- { "gpd1", 1, 0x0A0, 8, 0x714, 0x828, 0x914, 0xA14 }, | |||
- { "gpy0", 1, 0x0C0, 6, 0x718, 0x830, 0x918, 0xA18 }, | |||
- { "gpy1", 1, 0x0E0, 4, 0x71C, 0x838, 0x91C, 0xA1C }, | |||
- { "gpy2", 1, 0x100, 6, 0x720, 0x840, 0x920, 0xA20 }, | |||
- { "gpy3", 1, 0x120, 8, 0x724, 0x848, 0x924, 0xA24 }, | |||
- { "gpy4", 1, 0x140, 8, 0x728, 0x850, 0x928, 0xA28 }, | |||
- { "gpy5", 1, 0x160, 8, 0x72C, 0x858, 0x92C, 0xA2C }, | |||
- { "gpy6", 1, 0x180, 8, 0x730, 0x860, 0x930, 0xA30 }, | |||
- | |||
- /* Next 46 */ | |||
- { "gpe0", 2, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 }, | |||
- { "gpe1", 2, 0x020, 2, 0x704, 0x808, 0x904, 0xA04 }, | |||
- { "gpf0", 2, 0x040, 6, 0x708, 0x810, 0x908, 0xA08 }, | |||
- { "gpf1", 2, 0x060, 8, 0x70C, 0x818, 0x90C, 0xA0C }, | |||
- { "gpg0", 2, 0x080, 8, 0x710, 0x820, 0x910, 0xA10 }, | |||
- { "gpg1", 2, 0x0A0, 8, 0x714, 0x828, 0x914, 0xA14 }, | |||
- { "gpg2", 2, 0x0C0, 2, 0x718, 0x830, 0x918, 0xA18 }, | |||
- { "gpj4", 2, 0x0E0, 4, 0x71C, 0x838, 0x91C, 0xA1C }, | |||
- | |||
- /* Next 54 */ | |||
- { "gpa0", 3, 0x000, 8, 0x700, 0x800, 0x900, 0xA00 }, | |||
- { "gpa1", 3, 0x020, 6, 0x704, 0x808, 0x904, 0xA04 }, | |||
- { "gpa2", 3, 0x040, 8, 0x708, 0x810, 0x908, 0xA08 }, | |||
- { "gpb0", 3, 0x060, 5, 0x70C, 0x818, 0x90C, 0xA0C }, | |||
- { "gpb1", 3, 0x080, 5, 0x710, 0x820, 0x910, 0xA10 }, | |||
- { "gpb2", 3, 0x0A0, 4, 0x714, 0x828, 0x914, 0xA14 }, | |||
- { "gpb3", 3, 0x0C0, 8, 0x718, 0x830, 0x918, 0xA18 }, | |||
- { "gpb4", 3, 0x0E0, 2, 0x71C, 0x838, 0x91C, 0xA1C }, | |||
- { "gph0", 3, 0x100, 8, 0x720, 0x840, 0x920, 0xA20 }, | |||
- | |||
- /* Last 7 */ | |||
- { "gpz", 4, 0x000, 7, 0x700, 0x800, 0x900, 0xA00 }, | |||
- | |||
- { NULL, -1, -1, -1, -1, -1, -1, -1 }, | |||
-}; | |||
- | |||
-static int | |||
-get_bank(struct pad_softc *sc, int gpio_number, | |||
- struct gpio_bank *bank, int *pin_shift) | |||
-{ | |||
- int ngpio; | |||
- int i; | |||
- int n; | |||
- | |||
- n = 0; | |||
- for (i = 0; sc->gpio_map[i].ngpio != -1; i++) { | |||
- ngpio = sc->gpio_map[i].ngpio; | |||
- | |||
- if ((n + ngpio) > gpio_number) { | |||
- *bank = sc->gpio_map[i]; | |||
- *pin_shift = (gpio_number - n); | |||
- return (0); | |||
- } | |||
- | |||
- n += ngpio; | |||
- } | |||
- | |||
- return (-1); | |||
-} | |||
- | |||
-static int | |||
-port_intr(void *arg) | |||
-{ | |||
- struct port_softc *sc; | |||
- | |||
- sc = arg; | |||
- | |||
- return (FILTER_HANDLED); | |||
-} | |||
- | |||
-static void | |||
-ext_intr(void *arg) | |||
-{ | |||
- struct pad_softc *sc; | |||
- void (*ih) (void *); | |||
- void *ih_user; | |||
- int ngpio; | |||
- int found; | |||
- int reg; | |||
- int i,j; | |||
- int n,k; | |||
- | |||
- sc = arg; | |||
- | |||
- n = 0; | |||
- for (i = 0; sc->gpio_map[i].ngpio != -1; i++) { | |||
- found = 0; | |||
- ngpio = sc->gpio_map[i].ngpio; | |||
- | |||
- if (sc->gpio_map[i].pend == 0) { | |||
- n += ngpio; | |||
- continue; | |||
- } | |||
- | |||
- reg = READ4(sc, sc->gpio_map[i].port, sc->gpio_map[i].pend); | |||
- | |||
- for (j = 0; j < ngpio; j++) { | |||
- if (reg & (1 << j)) { | |||
- found = 1; | |||
- | |||
- k = (n + j); | |||
- if (intr_map[k].enabled == 1) { | |||
- ih = intr_map[k].ih; | |||
- ih_user = intr_map[k].ih_user; | |||
- ih(ih_user); | |||
- } | |||
- } | |||
- } | |||
- | |||
- if (found) { | |||
- /* ACK */ | |||
- WRITE4(sc, sc->gpio_map[i].port, sc->gpio_map[i].pend, reg); | |||
- } | |||
- | |||
- n += ngpio; | |||
- } | |||
-} | |||
- | |||
-int | |||
-pad_setup_intr(int gpio_number, void (*ih)(void *), void *ih_user) | |||
-{ | |||
- struct interrupt_entry *entry; | |||
- struct pad_intr *pad_irq; | |||
- struct gpio_bank bank; | |||
- struct pad_softc *sc; | |||
- int pin_shift; | |||
- int reg; | |||
- int i; | |||
- | |||
- sc = gpio_sc; | |||
- | |||
- if (sc == NULL) { | |||
- printf("%s: Error: pad is not attached\n", __func__); | |||
- return (-1); | |||
- } | |||
- | |||
- if (get_bank(sc, gpio_number, &bank, &pin_shift) != 0) | |||
- return (-1); | |||
- | |||
- entry = NULL; | |||
- for (i = 0; i < N_EXT_INTS; i++) | |||
- if (sc->interrupt_table[i].gpio_number == gpio_number) | |||
- entry = &(sc->interrupt_table[i]); | |||
- | |||
- if (entry == NULL) { | |||
- device_printf(sc->dev, "Cant find interrupt source for %d\n", | |||
- gpio_number); | |||
- return (-1); | |||
- } | |||
- | |||
-#if 0 | |||
- printf("Request interrupt name %s\n", entry->combiner_source_ | |||
-#endif | |||
- | |||
- pad_irq = &intr_map[gpio_number]; | |||
- pad_irq->enabled = 1; | |||
- pad_irq->ih = ih; | |||
- pad_irq->ih_user = ih_user; | |||
- | |||
- /* Setup port as external interrupt source */ | |||
- reg = READ4(sc, bank.port, bank.con); | |||
- reg |= (0xf << (pin_shift * 4)); | |||
-#if 0 | |||
- printf("writing 0x%08x to 0x%08x\n", reg, bank.con); | |||
-#endif | |||
- WRITE4(sc, bank.port, bank.con, reg); | |||
- | |||
- /* | |||
- * Configure interrupt pin | |||
- * | |||
- * 0x0 = Sets Low level | |||
- * 0x1 = Sets High level | |||
- * 0x2 = Triggers Falling edge | |||
- * 0x3 = Triggers Rising edge | |||
- * 0x4 = Triggers Both edge | |||
- * | |||
- * TODO: add parameter. For now configure as 0x0 | |||
- */ | |||
- reg = READ4(sc, bank.port, bank.ext_con); | |||
- reg &= ~(0x7 << (pin_shift * 4)); | |||
- WRITE4(sc, bank.port, bank.ext_con, reg); | |||
- | |||
- /* Unmask */ | |||
- reg = READ4(sc, bank.port, bank.mask); | |||
- reg &= ~(1 << pin_shift); | |||
- WRITE4(sc, bank.port, bank.mask, reg); | |||
- | |||
- combiner_setup_i | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-pad_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (ofw_bus_search_c | |||
- device_set_desc(dev, "Exynos Pad Control"); | |||
- return (BUS_PROBE_DEFAUL | |||
- } | |||
- | |||
- return (ENXIO); | |||
-} | |||
- | |||
-static int | |||
-pad_attach(device_t dev) | |||
-{ | |||
- struct gpio_bank bank; | |||
- struct pad_softc *sc; | |||
- int pin_shift; | |||
- int reg; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- mtx_init(&sc->sc_mtx, device_get_nameu | |||
- | |||
- sc->model = ofw_bus_search_c | |||
- switch (sc->model) { | |||
- case EXYNOS5250: | |||
- sc->pad_spec = pad_spec_5250; | |||
- sc->gpio_map = gpio_map_5250; | |||
- sc->interrupt_table = interrupt_table_ | |||
- sc->gpio_npins = 253; | |||
- sc->nports = 4; | |||
- break; | |||
- case EXYNOS5420: | |||
- sc->pad_spec = pad_spec_5420; | |||
- sc->gpio_map = gpio_map_5420; | |||
- sc->interrupt_table = interrupt_table_ | |||
- sc->gpio_npins = 232; | |||
- sc->nports = 5; | |||
- break; | |||
- default: | |||
- goto fail; | |||
- } | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- goto fail; | |||
- } | |||
- | |||
- /* Memory interface */ | |||
- | |||
- for (i = 0; i < sc->nports; i++) { | |||
- sc->bst[i] = rman_get_bustag(sc->res[i]); | |||
- sc->bsh[i] = rman_get_bushand | |||
- } | |||
- | |||
- sc->dev = dev; | |||
- | |||
- gpio_sc = sc; | |||
- | |||
- for (i = 0; i < sc->nports; i++) { | |||
- if ((bus_setup_intr(dev, sc->res[sc->nports + i], | |||
- INTR_TYPE_BIO | INTR_MPSAFE, port_intr, | |||
- NULL, sc, &sc->gpio_ih[i]))) { | |||
- device_printf(dev, | |||
- "ERROR: Unable to register interrupt handler\n"); | |||
- goto fail; | |||
- } | |||
- } | |||
- | |||
- for (i = 0; i < sc->gpio_npins; i++) { | |||
- sc->gpio_pins[i].gp_pin = i; | |||
- sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; | |||
- | |||
- if (get_bank(sc, i, &bank, &pin_shift) != 0) | |||
- continue; | |||
- | |||
- pin_shift *= 4; | |||
- | |||
- reg = READ4(sc, bank.port, bank.con); | |||
- if (reg & (PIN_OUT << pin_shift)) | |||
- sc->gpio_pins[i].gp_flags = GPIO_PIN_OUTPUT; | |||
- else | |||
- sc->gpio_pins[i].gp_flags = GPIO_PIN_INPUT; | |||
- | |||
- /* TODO: add other pin statuses */ | |||
- | |||
- snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, | |||
- "pad%d.%d", device_get_unit(dev), i); | |||
- } | |||
- sc->busdev = gpiobus_attach_b | |||
- if (sc->busdev == NULL) | |||
- goto fail; | |||
- | |||
- return (0); | |||
- | |||
-fail: | |||
- for (i = 0; i < sc->nports; i++) { | |||
- if (sc->gpio_ih[i]) | |||
- bus_teardown_int | |||
- sc->gpio_ih[i]); | |||
- } | |||
- bus_release_reso | |||
- mtx_destroy(&sc->sc_mtx); | |||
- | |||
- return (ENXIO); | |||
-} | |||
- | |||
-static device_t | |||
-pad_get_bus(device_t dev) | |||
-{ | |||
- struct pad_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- return (sc->busdev); | |||
-} | |||
- | |||
-static int | |||
-pad_pin_max(device_t dev, int *maxpin) | |||
-{ | |||
- struct pad_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- *maxpin = sc->gpio_npins - 1; | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-pad_pin_getname(device_t dev, uint32_t pin, char *name) | |||
-{ | |||
- struct pad_softc *sc; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- for (i = 0; i < sc->gpio_npins; i++) { | |||
- if (sc->gpio_pins[i].gp_pin == pin) | |||
- break; | |||
- } | |||
- | |||
- if (i >= sc->gpio_npins) | |||
- return (EINVAL); | |||
- | |||
- GPIO_LOCK(sc); | |||
- memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME); | |||
- GPIO_UNLOCK(sc); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-pad_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) | |||
-{ | |||
- struct pad_softc *sc; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- for (i = 0; i < sc->gpio_npins; i++) { | |||
- if (sc->gpio_pins[i].gp_pin == pin) | |||
- break; | |||
- } | |||
- | |||
- if (i >= sc->gpio_npins) | |||
- return (EINVAL); | |||
- | |||
- GPIO_LOCK(sc); | |||
- *caps = sc->gpio_pins[i].gp_caps; | |||
- GPIO_UNLOCK(sc); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-pad_pin_getflags | |||
-{ | |||
- struct pad_softc *sc; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- for (i = 0; i < sc->gpio_npins; i++) { | |||
- if (sc->gpio_pins[i].gp_pin == pin) | |||
- break; | |||
- } | |||
- | |||
- if (i >= sc->gpio_npins) | |||
- return (EINVAL); | |||
- | |||
- GPIO_LOCK(sc); | |||
- *flags = sc->gpio_pins[i].gp_flags; | |||
- GPIO_UNLOCK(sc); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-pad_pin_get(device_t dev, uint32_t pin, unsigned int *val) | |||
-{ | |||
- struct gpio_bank bank; | |||
- struct pad_softc *sc; | |||
- int pin_shift; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- for (i = 0; i < sc->gpio_npins; i++) { | |||
- if (sc->gpio_pins[i].gp_pin == pin) | |||
- break; | |||
- } | |||
- | |||
- if (i >= sc->gpio_npins) | |||
- return (EINVAL); | |||
- | |||
- if (get_bank(sc, pin, &bank, &pin_shift) != 0) | |||
- return (EINVAL); | |||
- | |||
- GPIO_LOCK(sc); | |||
- if (READ4(sc, bank.port, bank.con + 0x4) & (1 << pin_shift)) | |||
- *val = 1; | |||
- else | |||
- *val = 0; | |||
- GPIO_UNLOCK(sc); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-pad_pin_toggle(device_t dev, uint32_t pin) | |||
-{ | |||
- struct gpio_bank bank; | |||
- struct pad_softc *sc; | |||
- int pin_shift; | |||
- int reg; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- for (i = 0; i < sc->gpio_npins; i++) { | |||
- if (sc->gpio_pins[i].gp_pin == pin) | |||
- break; | |||
- } | |||
- | |||
- if (i >= sc->gpio_npins) | |||
- return (EINVAL); | |||
- | |||
- if (get_bank(sc, pin, &bank, &pin_shift) != 0) | |||
- return (EINVAL); | |||
- | |||
- GPIO_LOCK(sc); | |||
- reg = READ4(sc, bank.port, bank.con + 0x4); | |||
- if (reg & (1 << pin_shift)) | |||
- reg &= ~(1 << pin_shift); | |||
- else | |||
- reg |= (1 << pin_shift); | |||
- WRITE4(sc, bank.port, bank.con + 0x4, reg); | |||
- GPIO_UNLOCK(sc); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static void | |||
-pad_pin_configur | |||
- unsigned int flags) | |||
-{ | |||
- struct gpio_bank bank; | |||
- int pin_shift; | |||
- int reg; | |||
- | |||
- GPIO_LOCK(sc); | |||
- | |||
- /* | |||
- * Manage input/output | |||
- */ | |||
- if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { | |||
- pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); | |||
- | |||
- if (get_bank(sc, pin->gp_pin, &bank, &pin_shift) != 0) | |||
- return; | |||
- | |||
- pin_shift *= 4; | |||
- | |||
-#if 0 | |||
- printf("bank is 0x%08x pin_shift %d\n", bank.con, pin_shift); | |||
-#endif | |||
- | |||
- if (flags & GPIO_PIN_OUTPUT) { | |||
- pin->gp_flags |= GPIO_PIN_OUTPUT; | |||
- reg = READ4(sc, bank.port, bank.con); | |||
- reg &= ~(0xf << pin_shift); | |||
- reg |= (PIN_OUT << pin_shift); | |||
- WRITE4(sc, bank.port, bank.con, reg); | |||
- } else { | |||
- pin->gp_flags |= GPIO_PIN_INPUT; | |||
- reg = READ4(sc, bank.port, bank.con); | |||
- reg &= ~(0xf << pin_shift); | |||
- WRITE4(sc, bank.port, bank.con, reg); | |||
- } | |||
- } | |||
- | |||
- GPIO_UNLOCK(sc); | |||
-} | |||
- | |||
-static int | |||
-pad_pin_setflags | |||
-{ | |||
- struct pad_softc *sc; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- for (i = 0; i < sc->gpio_npins; i++) { | |||
- if (sc->gpio_pins[i].gp_pin == pin) | |||
- break; | |||
- } | |||
- | |||
- if (i >= sc->gpio_npins) | |||
- return (EINVAL); | |||
- | |||
- pad_pin_configur | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-pad_pin_set(device_t dev, uint32_t pin, unsigned int value) | |||
-{ | |||
- struct pad_softc *sc; | |||
- struct gpio_bank bank; | |||
- int pin_shift; | |||
- int reg; | |||
- int i; | |||
- | |||
- sc = device_get_softc | |||
- for (i = 0; i < sc->gpio_npins; i++) { | |||
- if (sc->gpio_pins[i].gp_pin == pin) | |||
- break; | |||
- } | |||
- | |||
- if (i >= sc->gpio_npins) | |||
- return (EINVAL); | |||
- | |||
- if (get_bank(sc, pin, &bank, &pin_shift) != 0) | |||
- return (EINVAL); | |||
- | |||
- GPIO_LOCK(sc); | |||
- reg = READ4(sc, bank.port, bank.con + 0x4); | |||
- reg &= ~(PIN_OUT << pin_shift); | |||
- if (value) | |||
- reg |= (PIN_OUT << pin_shift); | |||
- WRITE4(sc, bank.port, bank.con + 0x4, reg); | |||
- GPIO_UNLOCK(sc); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static device_method_t pad_methods[] = { | |||
- DEVMETHOD(device_probe, pad_probe), | |||
- DEVMETHOD(device_attach, pad_attach), | |||
- | |||
- /* GPIO protocol */ | |||
- DEVMETHOD(gpio_get_bus, pad_get_bus), | |||
- DEVMETHOD(gpio_pin_max, pad_pin_max), | |||
- DEVMETHOD(gpio_pin_getname | |||
- DEVMETHOD(gpio_pin_getcaps | |||
- DEVMETHOD(gpio_pin_getflag | |||
- DEVMETHOD(gpio_pin_get, pad_pin_get), | |||
- DEVMETHOD(gpio_pin_toggle, | |||
- DEVMETHOD(gpio_pin_setflag | |||
- DEVMETHOD(gpio_pin_set, pad_pin_set), | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t pad_driver = { | |||
- "gpio", | |||
- pad_methods, | |||
- sizeof(struct pad_softc), | |||
-}; | |||
- | |||
-static devclass_t pad_devclass; | |||
- | |||
-DRIVER_MODULE(pad, simplebus, pad_driver, pad_devclass, 0, 0); |
@@ -1,29 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- * | |||
- * $FreeBSD$ | |||
- */ | |||
- | |||
-int pad_setup_intr(int gpio_number, void (*ih)(void *), void *ih_user); |
@@ -1,179 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Exynos 5 Power Management Unit (PMU) | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_common.h> | |||
-#include <arm/samsung/exynos/exynos5_pmu.h> | |||
- | |||
-#define EXYNOS5250 1 | |||
-#define EXYNOS5420 2 | |||
- | |||
-/* PWR control */ | |||
-#define EXYNOS5_PWR_USBH | |||
-#define EXYNOS5_USBDRD_P | |||
-#define EXYNOS5420_USBDR | |||
- | |||
-#define PHY_POWER_ON 1 | |||
-#define PHY_POWER_OFF 0 | |||
- | |||
-struct pmu_softc { | |||
- struct resource *res[1]; | |||
- bus_space_tag_t bst; | |||
- bus_space_handle | |||
- device_t dev; | |||
- int model; | |||
-}; | |||
- | |||
-struct pmu_softc *pmu_sc; | |||
- | |||
-static struct ofw_compat_data compat_data[] = { | |||
- {"samsung,exynos54 | |||
- {"samsung,exynos52 | |||
- {NULL, 0} | |||
-}; | |||
- | |||
-static struct resource_spec pmu_spec[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static int | |||
-pmu_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (ofw_bus_search_c | |||
- device_set_desc(dev, "Samsung Exynos 5 Power Management Unit"); | |||
- return (BUS_PROBE_DEFAUL | |||
- } | |||
- | |||
- return (ENXIO); | |||
-} | |||
- | |||
-int | |||
-usb2_phy_power_o | |||
-{ | |||
- struct pmu_softc *sc; | |||
- | |||
- sc = pmu_sc; | |||
- if (sc == NULL) | |||
- return (-1); | |||
- | |||
- /* EHCI */ | |||
- WRITE4(sc, EXYNOS5_PWR_USBH | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-int | |||
-usbdrd_phy_power | |||
-{ | |||
- struct pmu_softc *sc; | |||
- | |||
- sc = pmu_sc; | |||
- if (sc == NULL) | |||
- return (-1); | |||
- | |||
- /* | |||
- * First XHCI controller (left-side USB port on chromebook2) | |||
- */ | |||
- WRITE4(sc, EXYNOS5_USBDRD_P | |||
- | |||
- /* | |||
- * Second XHCI controller (right-side USB port on chrombook2) | |||
- * Only available on 5420. | |||
- */ | |||
- if (sc->model == EXYNOS5420) | |||
- WRITE4(sc, EXYNOS5420_USBDR | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-pmu_attach(device_t dev) | |||
-{ | |||
- struct pmu_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- sc->dev = dev; | |||
- sc->model = ofw_bus_search_c | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* Memory interface */ | |||
- sc->bst = rman_get_bustag(sc->res[0]); | |||
- sc->bsh = rman_get_bushand | |||
- | |||
- pmu_sc = sc; | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static device_method_t pmu_methods[] = { | |||
- DEVMETHOD(device_probe, pmu_probe), | |||
- DEVMETHOD(device_attach, pmu_attach), | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t pmu_driver = { | |||
- "pmu", | |||
- pmu_methods, | |||
- sizeof(struct pmu_softc), | |||
-}; | |||
- | |||
-static devclass_t pmu_devclass; | |||
- | |||
-DRIVER_MODULE(pmu, simplebus, pmu_driver, pmu_devclass, 0, 0); |
@@ -1,30 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- * | |||
- * $FreeBSD$ | |||
- */ | |||
- | |||
-int usb2_phy_power_o | |||
-int usbdrd_phy_power |
@@ -1,234 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * Exynos 5 Serial Peripheral Interface (SPI) | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
- | |||
-#include <dev/spibus/spi.h> | |||
-#include <dev/spibus/spibusvar.h> | |||
- | |||
-#include "spibus_if.h" | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_common.h> | |||
- | |||
-#define CH_CFG 0x00 /* SPI configuration */ | |||
-#define SW_RST (1 << 5) /* Reset */ | |||
-#define RX_CH_ON (1 << 1) /* SPI Rx Channel On */ | |||
-#define TX_CH_ON (1 << 0) /* SPI Tx Channel On */ | |||
-#define MODE_CFG 0x08 /* FIFO control */ | |||
-#define CS_REG 0x0C /* slave selection control */ | |||
-#define NSSOUT (1 << 0) | |||
-#define SPI_INT_EN 0x10 /* interrupt enable */ | |||
-#define SPI_STATUS 0x14 /* SPI status */ | |||
-#define TX_FIFO_LVL_S 6 | |||
-#define TX_FIFO_LVL_M 0x1ff | |||
-#define RX_FIFO_LVL_S 15 | |||
-#define RX_FIFO_LVL_M 0x1ff | |||
-#define SPI_TX_DATA 0x18 /* Tx data */ | |||
-#define SPI_RX_DATA 0x1C /* Rx data */ | |||
-#define PACKET_CNT_REG 0x20 /* packet count */ | |||
-#define PENDING_CLR_REG 0x24 /* interrupt pending clear */ | |||
-#define SWAP_CFG 0x28 /* swap configuration */ | |||
-#define FB_CLK_SEL 0x2C /* feedback clock selection */ | |||
-#define FB_CLK_180 0x2 /* 180 degree phase lagging */ | |||
- | |||
-struct spi_softc { | |||
- struct resource *res[2]; | |||
- bus_space_tag_t bst; | |||
- bus_space_handle | |||
- device_t dev; | |||
-}; | |||
- | |||
-struct spi_softc *spi_sc; | |||
- | |||
-static struct resource_spec spi_spec[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 0, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static int | |||
-spi_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (!ofw_bus_is_compa | |||
- return (ENXIO); | |||
- | |||
- device_set_desc(dev, "Exynos 5 Serial Peripheral Interface (SPI)"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-spi_attach(device_t dev) | |||
-{ | |||
- struct spi_softc *sc; | |||
- int reg; | |||
- | |||
- sc = device_get_softc | |||
- sc->dev = dev; | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* Memory interface */ | |||
- sc->bst = rman_get_bustag(sc->res[0]); | |||
- sc->bsh = rman_get_bushand | |||
- | |||
- spi_sc = sc; | |||
- | |||
- WRITE4(sc, FB_CLK_SEL, FB_CLK_180); | |||
- | |||
- reg = READ4(sc, CH_CFG); | |||
- reg |= (RX_CH_ON | TX_CH_ON); | |||
- WRITE4(sc, CH_CFG, reg); | |||
- | |||
- device_add_child | |||
- return (bus_generic_atta | |||
-} | |||
- | |||
-static int | |||
-spi_txrx(struct spi_softc *sc, uint8_t *out_buf, | |||
- uint8_t *in_buf, int bufsz, int cs) | |||
-{ | |||
- uint32_t reg; | |||
- uint32_t i; | |||
- | |||
- if (bufsz == 0) { | |||
- /* Nothing to transfer */ | |||
- return (0); | |||
- } | |||
- | |||
- /* Reset registers */ | |||
- reg = READ4(sc, CH_CFG); | |||
- reg |= SW_RST; | |||
- WRITE4(sc, CH_CFG, reg); | |||
- reg &= ~SW_RST; | |||
- WRITE4(sc, CH_CFG, reg); | |||
- | |||
- /* Assert CS */ | |||
- reg = READ4(sc, CS_REG); | |||
- reg &= ~NSSOUT; | |||
- WRITE4(sc, CS_REG, reg); | |||
- | |||
- for (i = 0; i < bufsz; i++) { | |||
- /* TODO: Implement FIFO operation */ | |||
- | |||
- /* Wait all the data shifted out */ | |||
- while (READ4(sc, SPI_STATUS) & \ | |||
- (TX_FIFO_LVL_M << TX_FIFO_LVL_S)) | |||
- continue; | |||
- | |||
- WRITE1(sc, SPI_TX_DATA, out_buf[i]); | |||
- | |||
- /* Wait until no data available */ | |||
- while ((READ4(sc, SPI_STATUS) & \ | |||
- (RX_FIFO_LVL_M << RX_FIFO_LVL_S)) == 0) | |||
- continue; | |||
- | |||
- in_buf[i] = READ1(sc, SPI_RX_DATA); | |||
- } | |||
- | |||
- /* Deassert CS */ | |||
- reg = READ4(sc, CS_REG); | |||
- reg |= NSSOUT; | |||
- WRITE4(sc, CS_REG, reg); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-spi_transfer(device_t dev, device_t child, struct spi_command *cmd) | |||
-{ | |||
- struct spi_softc *sc; | |||
- uint32_t cs; | |||
- | |||
- sc = device_get_softc | |||
- | |||
- KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, | |||
- ("%s: TX/RX command sizes should be equal", __func__)); | |||
- KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, | |||
- ("%s: TX/RX data sizes should be equal", __func__)); | |||
- | |||
- /* get the proper chip select */ | |||
- spibus_get_cs(child, &cs); | |||
- | |||
- cs &= ~SPIBUS_CS_HIGH; | |||
- | |||
- /* Command */ | |||
- spi_txrx(sc, cmd->tx_cmd, cmd->rx_cmd, cmd->tx_cmd_sz, cs); | |||
- | |||
- /* Data */ | |||
- spi_txrx(sc, cmd->tx_data, cmd->rx_data, cmd->tx_data_sz, cs); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static device_method_t spi_methods[] = { | |||
- DEVMETHOD(device_probe, spi_probe), | |||
- DEVMETHOD(device_attach, spi_attach), | |||
- | |||
- /* SPI interface */ | |||
- DEVMETHOD(spibus_transfer, | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t spi_driver = { | |||
- "spi", | |||
- spi_methods, | |||
- sizeof(struct spi_softc), | |||
-}; | |||
- | |||
-static devclass_t spi_devclass; | |||
- | |||
-DRIVER_MODULE(spi, simplebus, spi_driver, spi_devclass, 0, 0); |
@@ -1,271 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-/* | |||
- * DWC3 USB 3.0 DRD (dual role device) PHY | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/malloc.h> | |||
-#include <sys/rman.h> | |||
-#include <sys/timeet.h> | |||
-#include <sys/timetc.h> | |||
-#include <sys/watchdog.h> | |||
-#include <sys/gpio.h> | |||
- | |||
-#include <dev/ofw/openfirm.h> | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/cpu.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_common.h> | |||
-#include <arm/samsung/exynos/exynos5_pmu.h> | |||
- | |||
-#include "gpio_if.h" | |||
- | |||
-#define USB_DRD_LINKSYST | |||
-#define LINKSYSTEM_FLADJ | |||
-#define LINKSYSTEM_FLADJ | |||
-#define LINKSYSTEM_XHCI_ | |||
-#define USB_DRD_PHYUTMI 0x08 | |||
-#define PHYUTMI_OTGDISAB | |||
-#define PHYUTMI_FORCESUS | |||
-#define PHYUTMI_FORCESLE | |||
-#define USB_DRD_PHYPIPE 0x0c | |||
-#define USB_DRD_PHYCLKRS | |||
-#define PHYCLKRST_PORTRE | |||
-#define PHYCLKRST_COMMON | |||
-#define PHYCLKRST_EN_UTM | |||
-#define PHYCLKRST_SSC_RE | |||
-#define PHYCLKRST_SSC_RE | |||
-#define PHYCLKRST_SSC_RA | |||
-#define PHYCLKRST_SSC_RA | |||
-#define PHYCLKRST_SSC_EN | |||
-#define PHYCLKRST_REF_SS | |||
-#define PHYCLKRST_REF_CL | |||
-#define PHYCLKRST_MPLL_M | |||
-#define PHYCLKRST_MPLL_M | |||
-#define PHYCLKRST_MPLL_M | |||
-#define PHYCLKRST_MPLL_M | |||
-#define PHYCLKRST_MPLL_M | |||
-#define PHYCLKRST_MPLL_M | |||
-#define PHYCLKRST_FSEL_U | |||
-#define PHYCLKRST_FSEL_P | |||
-#define PHYCLKRST_FSEL(x) ((x) << 5) | |||
-#define PHYCLKRST_FSEL_9 | |||
-#define PHYCLKRST_FSEL_1 | |||
-#define PHYCLKRST_FSEL_1 | |||
-#define PHYCLKRST_FSEL_1 | |||
-#define PHYCLKRST_FSEL_2 | |||
-#define PHYCLKRST_FSEL_2 | |||
-#define PHYCLKRST_FSEL_5 | |||
-#define PHYCLKRST_RETENA | |||
-#define PHYCLKRST_REFCLK | |||
-#define PHYCLKRST_REFCLK | |||
-#define PHYCLKRST_REFCLK | |||
-#define USB_DRD_PHYREG0 0x14 | |||
-#define USB_DRD_PHYREG1 0x18 | |||
-#define USB_DRD_PHYPARAM | |||
-#define PHYPARAM0_REF_US | |||
-#define PHYPARAM0_REF_LO | |||
-#define PHYPARAM0_REF_LO | |||
-#define USB_DRD_PHYPARAM | |||
-#define PHYPARAM1_PCS_TX | |||
-#define PHYPARAM1_PCS_TX | |||
-#define USB_DRD_PHYTERM 0x24 | |||
-#define USB_DRD_PHYTEST 0x28 | |||
-#define PHYTEST_POWERDOW | |||
-#define PHYTEST_POWERDOW | |||
-#define USB_DRD_PHYADP 0x2c | |||
-#define USB_DRD_PHYUTMIC | |||
-#define PHYUTMICLKSEL_UT | |||
-#define USB_DRD_PHYRESUM | |||
-#define USB_DRD_LINKPORT | |||
- | |||
-struct usb_phy_softc { | |||
- struct resource *res[1]; | |||
- bus_space_tag_t bst; | |||
- bus_space_handle | |||
- device_t dev; | |||
-}; | |||
- | |||
-static struct resource_spec usb_phy_spec[] = { | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static int | |||
-usb_phy_probe(device_t dev) | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (!ofw_bus_is_compa | |||
- return (ENXIO); | |||
- | |||
- device_set_desc(dev, "Samsung Exynos 5 USB PHY"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-vbus_on(struct usb_phy_softc *sc) | |||
-{ | |||
- pcell_t dts_value[3]; | |||
- device_t gpio_dev; | |||
- phandle_t node; | |||
- pcell_t pin; | |||
- int len; | |||
- | |||
- if ((node = ofw_bus_get_node | |||
- return (-1); | |||
- | |||
- /* Power pin */ | |||
- if ((len = OF_getproplen(node, "vbus-supply")) <= 0) | |||
- return (-1); | |||
- OF_getencprop(node, "vbus-supply", dts_value, len); | |||
- pin = dts_value[0]; | |||
- | |||
- gpio_dev = devclass_get_dev | |||
- if (gpio_dev == NULL) { | |||
- device_printf(sc->dev, "can't find gpio_dev\n"); | |||
- return (1); | |||
- } | |||
- | |||
- GPIO_PIN_SETFLAG | |||
- GPIO_PIN_SET(gpio_dev, pin, GPIO_PIN_HIGH); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-usb3_phy_init(struct usb_phy_softc *sc) | |||
-{ | |||
- int reg; | |||
- | |||
- /* Reset USB 3.0 PHY */ | |||
- WRITE4(sc, USB_DRD_PHYREG0, | |||
- | |||
- reg = READ4(sc, USB_DRD_PHYPARAM | |||
- /* PHY CLK src */ | |||
- reg &= ~(PHYPARAM0_REF_US | |||
- reg &= ~(PHYPARAM0_REF_LO | |||
- reg |= (PHYPARAM0_REF_LO | |||
- WRITE4(sc, USB_DRD_PHYPARAM | |||
- WRITE4(sc, USB_DRD_PHYRESUM | |||
- | |||
- reg = (LINKSYSTEM_XHCI_ | |||
- LINKSYSTEM_FLADJ | |||
- WRITE4(sc, USB_DRD_LINKSYST | |||
- | |||
- reg = READ4(sc, USB_DRD_PHYPARAM | |||
- reg &= ~(PHYPARAM1_PCS_TX | |||
- reg |= (PHYPARAM1_PCS_TX | |||
- WRITE4(sc, USB_DRD_PHYPARAM | |||
- | |||
- reg = READ4(sc, USB_DRD_PHYUTMIC | |||
- reg |= (PHYUTMICLKSEL_UT | |||
- WRITE4(sc, USB_DRD_PHYUTMIC | |||
- | |||
- reg = READ4(sc, USB_DRD_PHYTEST); | |||
- reg &= ~(PHYTEST_POWERDOW | |||
- reg &= ~(PHYTEST_POWERDOW | |||
- WRITE4(sc, USB_DRD_PHYTEST, | |||
- | |||
- WRITE4(sc, USB_DRD_PHYUTMI, | |||
- | |||
- /* Clock */ | |||
- reg = (PHYCLKRST_REFCLK | |||
- reg |= (PHYCLKRST_FSEL(PHYCLKRST_FSEL_2 | |||
- reg |= (PHYCLKRST_MPLL_M | |||
- reg |= (PHYCLKRST_SSC_RE | |||
- reg |= (PHYCLKRST_RETENA | |||
- PHYCLKRST_REF_SS | |||
- PHYCLKRST_SSC_EN | |||
- PHYCLKRST_COMMON | |||
- PHYCLKRST_PORTRE | |||
- | |||
- WRITE4(sc, USB_DRD_PHYCLKRS | |||
- DELAY(50000); | |||
- reg &= ~PHYCLKRST_PORTRE | |||
- WRITE4(sc, USB_DRD_PHYCLKRS | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-usb_phy_attach(device_t dev) | |||
-{ | |||
- struct usb_phy_softc *sc; | |||
- | |||
- sc = device_get_softc | |||
- sc->dev = dev; | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* Memory interface */ | |||
- sc->bst = rman_get_bustag(sc->res[0]); | |||
- sc->bsh = rman_get_bushand | |||
- | |||
- vbus_on(sc); | |||
- | |||
- usbdrd_phy_power | |||
- | |||
- DELAY(100); | |||
- | |||
- usb3_phy_init(sc); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static device_method_t usb_phy_methods[] = { | |||
- DEVMETHOD(device_probe, usb_phy_probe), | |||
- DEVMETHOD(device_attach, usb_phy_attach), | |||
- { 0, 0 } | |||
-}; | |||
- | |||
-static driver_t usb_phy_driver = { | |||
- "usb_phy", | |||
- usb_phy_methods, | |||
- sizeof(struct usb_phy_softc), | |||
-}; | |||
- | |||
-static devclass_t usb_phy_devclass | |||
- | |||
-DRIVER_MODULE(usb_phy, simplebus, usb_phy_driver, usb_phy_devclass |
@@ -1,313 +0,0 @@ | |||
-/*- | |||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include "opt_bus.h" | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/kernel.h> | |||
-#include <sys/module.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/condvar.h> | |||
-#include <sys/rman.h> | |||
- | |||
-#include <dev/ofw/ofw_bus.h> | |||
-#include <dev/ofw/ofw_bus_subr.h> | |||
- | |||
-#include <dev/usb/usb.h> | |||
-#include <dev/usb/usbdi.h> | |||
-#include <dev/usb/usb_busdma.h> | |||
-#include <dev/usb/usb_process.h> | |||
-#include <dev/usb/usb_controller.h> | |||
-#include <dev/usb/usb_bus.h> | |||
-#include <dev/usb/controller/xhci.h> | |||
-#include <dev/usb/controller/xhcireg.h> | |||
- | |||
-#include <machine/bus.h> | |||
-#include <machine/resource.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos5_common.h> | |||
- | |||
-#include "opt_platform.h" | |||
- | |||
-#define GSNPSID 0x20 | |||
-#define GSNPSID_MASK 0xffff0000 | |||
-#define REVISION_MASK 0xffff | |||
-#define GCTL 0x10 | |||
-#define GCTL_PWRDNSCALE(n) ((n) << 19) | |||
-#define GCTL_U2RSTECN (1 << 16) | |||
-#define GCTL_CLK_BUS (0) | |||
-#define GCTL_CLK_PIPE (1) | |||
-#define GCTL_CLK_PIPEHAL | |||
-#define GCTL_CLK_M (3) | |||
-#define GCTL_CLK_S (6) | |||
-#define GCTL_PRTCAP(n) (((n) & (3 << 12)) >> 12) | |||
-#define GCTL_PRTCAPDIR(n) ((n) << 12) | |||
-#define GCTL_PRTCAP_HOST | |||
-#define GCTL_PRTCAP_DEVI | |||
-#define GCTL_PRTCAP_OTG 3 | |||
-#define GCTL_CORESOFTRES | |||
-#define GCTL_SCALEDOWN_M | |||
-#define GCTL_SCALEDOWN_S | |||
-#define GCTL_DISSCRAMBLE | |||
-#define GCTL_DSBLCLKGTNG | |||
-#define GHWPARAMS1 0x3c | |||
-#define GHWPARAMS1_EN_PW | |||
-#define GHWPARAMS1_EN_PW | |||
-#define GHWPARAMS1_EN_PW | |||
-#define GUSB2PHYCFG(n) (0x100 + (n * 0x04)) | |||
-#define GUSB2PHYCFG_PHYS | |||
-#define GUSB2PHYCFG_SUSP | |||
-#define GUSB3PIPECTL(n) (0x1c0 + (n * 0x04)) | |||
-#define GUSB3PIPECTL_PHY | |||
-#define GUSB3PIPECTL_SUS | |||
- | |||
-/* Forward declarations */ | |||
-static device_attach_t exynos_xhci_atta | |||
-static device_detach_t exynos_xhci_deta | |||
-static device_probe_t exynos_xhci_prob | |||
- | |||
-struct exynos_xhci_soft | |||
- device_t dev; | |||
- struct xhci_softc base; | |||
- struct resource *res[3]; | |||
- bus_space_tag_t bst; | |||
- bus_space_handle | |||
-}; | |||
- | |||
-static struct resource_spec exynos_xhci_spec | |||
- { SYS_RES_MEMORY, 0, RF_ACTIVE }, | |||
- { SYS_RES_MEMORY, 1, RF_ACTIVE }, | |||
- { SYS_RES_IRQ, 0, RF_ACTIVE }, | |||
- { -1, 0 } | |||
-}; | |||
- | |||
-static device_method_t xhci_methods[] = { | |||
- /* Device interface */ | |||
- DEVMETHOD(device_probe, exynos_xhci_prob | |||
- DEVMETHOD(device_attach, exynos_xhci_atta | |||
- DEVMETHOD(device_detach, exynos_xhci_deta | |||
- DEVMETHOD(device_suspend, bus_generic_susp | |||
- DEVMETHOD(device_resume, bus_generic_resu | |||
- DEVMETHOD(device_shutdown, | |||
- | |||
- DEVMETHOD_END | |||
-}; | |||
- | |||
-/* kobj_class definition */ | |||
-static driver_t xhci_driver = { | |||
- "xhci", | |||
- xhci_methods, | |||
- sizeof(struct xhci_softc) | |||
-}; | |||
- | |||
-static devclass_t xhci_devclass; | |||
- | |||
-DRIVER_MODULE(xhci, simplebus, xhci_driver, xhci_devclass, 0, 0); | |||
-MODULE_DEPEND(xhci, usb, 1, 1, 1); | |||
- | |||
-/* | |||
- * Public methods | |||
- */ | |||
-static int | |||
-exynos_xhci_prob | |||
-{ | |||
- | |||
- if (!ofw_bus_status_o | |||
- return (ENXIO); | |||
- | |||
- if (ofw_bus_is_compa | |||
- return (ENXIO); | |||
- | |||
- device_set_desc(dev, "Exynos USB 3.0 controller"); | |||
- return (BUS_PROBE_DEFAUL | |||
-} | |||
- | |||
-static int | |||
-dwc3_init(struct exynos_xhci_soft | |||
-{ | |||
- int hwparams1; | |||
- int rev; | |||
- int reg; | |||
- | |||
- rev = READ4(esc, GSNPSID); | |||
- if ((rev & GSNPSID_MASK) != 0x55330000) { | |||
- printf("It is not DWC3 controller\n"); | |||
- return (-1); | |||
- } | |||
- | |||
- /* Reset controller */ | |||
- WRITE4(esc, GCTL, GCTL_CORESOFTRES | |||
- WRITE4(esc, GUSB3PIPECTL(0), GUSB3PIPECTL_PHY | |||
- WRITE4(esc, GUSB2PHYCFG(0), GUSB2PHYCFG_PHYS | |||
- | |||
- DELAY(100000); | |||
- | |||
- reg = READ4(esc, GUSB3PIPECTL(0)); | |||
- reg &= ~(GUSB3PIPECTL_PHY | |||
- WRITE4(esc, GUSB3PIPECTL(0), reg); | |||
- | |||
- reg = READ4(esc, GUSB2PHYCFG(0)); | |||
- reg &= ~(GUSB2PHYCFG_PHYS | |||
- WRITE4(esc, GUSB2PHYCFG(0), reg); | |||
- | |||
- reg = READ4(esc, GCTL); | |||
- reg &= ~GCTL_CORESOFTRES | |||
- WRITE4(esc, GCTL, reg); | |||
- | |||
- hwparams1 = READ4(esc, GHWPARAMS1); | |||
- | |||
- reg = READ4(esc, GCTL); | |||
- reg &= ~(GCTL_SCALEDOWN_M | |||
- reg &= ~(GCTL_DISSCRAMBLE | |||
- | |||
- if (GHWPARAMS1_EN_PW | |||
- GHWPARAMS1_EN_PW | |||
- reg &= ~(GCTL_DSBLCLKGTNG | |||
- | |||
- if ((rev & REVISION_MASK) < 0x190a) | |||
- reg |= (GCTL_U2RSTECN); | |||
- WRITE4(esc, GCTL, reg); | |||
- | |||
- /* Set host mode */ | |||
- reg = READ4(esc, GCTL); | |||
- reg &= ~(GCTL_PRTCAPDIR(GCTL_PRTCAP_OTG)); | |||
- reg |= GCTL_PRTCAPDIR(GCTL_PRTCAP_HOST | |||
- WRITE4(esc, GCTL, reg); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos_xhci_atta | |||
-{ | |||
- struct exynos_xhci_soft | |||
- bus_space_handle | |||
- int err; | |||
- | |||
- esc->dev = dev; | |||
- | |||
- if (bus_alloc_resour | |||
- device_printf(dev, "could not allocate resources\n"); | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* XHCI registers */ | |||
- esc->base.sc_io_tag = rman_get_bustag(esc->res[0]); | |||
- bsh = rman_get_bushand | |||
- esc->base.sc_io_size = rman_get_size(esc->res[0]); | |||
- | |||
- /* DWC3 ctrl registers */ | |||
- esc->bst = rman_get_bustag(esc->res[1]); | |||
- esc->bsh = rman_get_bushand | |||
- | |||
- /* | |||
- * Set handle to USB related registers subregion used by | |||
- * generic XHCI driver. | |||
- */ | |||
- err = bus_space_subreg | |||
- esc->base.sc_io_size, &esc->base.sc_io_hdl); | |||
- if (err != 0) { | |||
- device_printf(dev, "Subregion failed\n"); | |||
- bus_release_reso | |||
- return (ENXIO); | |||
- } | |||
- | |||
- if (xhci_init(&esc->base, dev, 0)) { | |||
- device_printf(dev, "Could not initialize softc\n"); | |||
- bus_release_reso | |||
- return (ENXIO); | |||
- } | |||
- | |||
- /* Setup interrupt handler */ | |||
- err = bus_setup_intr(dev, esc->res[2], INTR_TYPE_BIO | INTR_MPSAFE, | |||
- NULL, (driver_intr_t *)xhci_interrupt, &esc->base, | |||
- &esc->base.sc_intr_hdl); | |||
- if (err) { | |||
- device_printf(dev, "Could not setup irq, %d\n", err); | |||
- esc->base.sc_intr_hdl = NULL; | |||
- goto error; | |||
- } | |||
- | |||
- /* Add USB device */ | |||
- esc->base.sc_bus.bdev = device_add_child | |||
- if (esc->base.sc_bus.bdev == NULL) { | |||
- device_printf(dev, "Could not add USB device\n"); | |||
- goto error; | |||
- } | |||
- device_set_ivars | |||
- strlcpy(esc->base.sc_vendor, "Samsung", sizeof(esc->base.sc_vendor)); | |||
- | |||
- dwc3_init(esc); | |||
- | |||
- err = xhci_halt_contro | |||
- if (err == 0) { | |||
- device_printf(dev, "Starting controller\n"); | |||
- err = xhci_start_contr | |||
- } | |||
- if (err == 0) { | |||
- device_printf(dev, "Controller started\n"); | |||
- err = device_probe_and | |||
- } | |||
- if (err != 0) | |||
- goto error; | |||
- return (0); | |||
- | |||
-error: | |||
- exynos_xhci_deta | |||
- return (ENXIO); | |||
-} | |||
- | |||
-static int | |||
-exynos_xhci_deta | |||
-{ | |||
- struct exynos_xhci_soft | |||
- int err; | |||
- | |||
- /* During module unload there are lots of children leftover */ | |||
- device_delete_ch | |||
- | |||
- xhci_halt_contro | |||
- | |||
- if (esc->res[2] && esc->base.sc_intr_hdl) { | |||
- err = bus_teardown_int | |||
- esc->base.sc_intr_hdl); | |||
- if (err) { | |||
- device_printf(dev, "Could not tear down IRQ," | |||
- " %d\n", err); | |||
- return (err); | |||
- } | |||
- } | |||
- | |||
- bus_release_reso | |||
- | |||
- xhci_uninit(&esc->base); | |||
- | |||
- return (0); | |||
-} |
@@ -1,388 +0,0 @@ | |||
-/* | |||
- * Copyright (c) 2003 Marcel Moolenaar | |||
- * Copyright (c) 2007-2009 Andrew Turner | |||
- * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com> | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |||
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |||
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
- */ | |||
- | |||
-#include <sys/cdefs.h> | |||
-__FBSDID("$FreeBSD$"); | |||
- | |||
-#include <sys/param.h> | |||
-#include <sys/systm.h> | |||
-#include <sys/bus.h> | |||
-#include <sys/conf.h> | |||
-#include <sys/cons.h> | |||
-#include <sys/rman.h> | |||
-#include <machine/bus.h> | |||
-#include <machine/intr.h> | |||
- | |||
-#include <dev/uart/uart.h> | |||
-#include <dev/uart/uart_cpu.h> | |||
-#include <dev/uart/uart_cpu_fdt.h> | |||
-#include <dev/uart/uart_bus.h> | |||
- | |||
-#include <arm/samsung/exynos/exynos_uart.h> | |||
- | |||
-#include "uart_if.h" | |||
- | |||
-#define DEF_CLK 100000000 | |||
- | |||
-static int sscomspeed(long, long); | |||
-static int exynos4210_uart_ | |||
- | |||
-/* | |||
- * Low-level UART interface. | |||
- */ | |||
-static int exynos4210_probe | |||
-static void exynos4210_init(struct uart_bas *bas, int, int, int, int); | |||
-static void exynos4210_term(struct uart_bas *bas); | |||
-static void exynos4210_putc(struct uart_bas *bas, int); | |||
-static int exynos4210_rxrea | |||
-static int exynos4210_getc(struct uart_bas *bas, struct mtx *mtx); | |||
- | |||
-extern SLIST_HEAD(uart_devinfo_lis | |||
- | |||
-static int | |||
-sscomspeed(long speed, long frequency) | |||
-{ | |||
- int x; | |||
- | |||
- if (speed <= 0 || frequency <= 0) | |||
- return (-1); | |||
- x = (frequency / 16) / speed; | |||
- return (x-1); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_uart_ | |||
- int stopbits, int parity) | |||
-{ | |||
- int brd, ulcon; | |||
- | |||
- ulcon = 0; | |||
- | |||
- switch(databits) { | |||
- case 5: | |||
- ulcon |= ULCON_LENGTH_5; | |||
- break; | |||
- case 6: | |||
- ulcon |= ULCON_LENGTH_6; | |||
- break; | |||
- case 7: | |||
- ulcon |= ULCON_LENGTH_7; | |||
- break; | |||
- case 8: | |||
- ulcon |= ULCON_LENGTH_8; | |||
- break; | |||
- default: | |||
- return (EINVAL); | |||
- } | |||
- | |||
- switch (parity) { | |||
- case UART_PARITY_NONE | |||
- ulcon |= ULCON_PARITY_NON | |||
- break; | |||
- case UART_PARITY_ODD: | |||
- ulcon |= ULCON_PARITY_ODD | |||
- break; | |||
- case UART_PARITY_EVEN | |||
- ulcon |= ULCON_PARITY_EVE | |||
- break; | |||
- case UART_PARITY_MARK | |||
- case UART_PARITY_SPAC | |||
- default: | |||
- return (EINVAL); | |||
- } | |||
- | |||
- if (stopbits == 2) | |||
- ulcon |= ULCON_STOP; | |||
- | |||
- uart_setreg(bas, SSCOM_ULCON, ulcon); | |||
- | |||
- brd = sscomspeed(baudrate, bas->rclk); | |||
- uart_setreg(bas, SSCOM_UBRDIV, brd); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-struct uart_ops uart_exynos4210_ | |||
- .probe = exynos4210_probe | |||
- .init = exynos4210_init, | |||
- .term = exynos4210_term, | |||
- .putc = exynos4210_putc, | |||
- .rxready = exynos4210_rxrea | |||
- .getc = exynos4210_getc, | |||
-}; | |||
- | |||
-static int | |||
-exynos4210_probe | |||
-{ | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static void | |||
-exynos4210_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, | |||
- int parity) | |||
-{ | |||
- | |||
- if (bas->rclk == 0) | |||
- bas->rclk = DEF_CLK; | |||
- | |||
- KASSERT(bas->rclk != 0, ("exynos4210_init: Invalid rclk")); | |||
- | |||
- uart_setreg(bas, SSCOM_UCON, 0); | |||
- uart_setreg(bas, SSCOM_UFCON, | |||
- UFCON_TXTRIGGER_ | |||
- UFCON_TXFIFO_RES | |||
- UFCON_FIFO_ENABL | |||
- exynos4210_uart_ | |||
- | |||
- /* Enable UART. */ | |||
- uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT | UCON_RXMODE_INT | | |||
- UCON_TOINT); | |||
- uart_setreg(bas, SSCOM_UMCON, UMCON_RTS); | |||
-} | |||
- | |||
-static void | |||
-exynos4210_term(struct uart_bas *bas) | |||
-{ | |||
- /* XXX */ | |||
-} | |||
- | |||
-static void | |||
-exynos4210_putc(struct uart_bas *bas, int c) | |||
-{ | |||
- | |||
- while ((bus_space_read_4 | |||
- UFSTAT_TXFULL) == UFSTAT_TXFULL) | |||
- continue; | |||
- | |||
- uart_setreg(bas, SSCOM_UTXH, c); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_rxrea | |||
-{ | |||
- | |||
- return ((uart_getreg(bas, SSCOM_UTRSTAT) & UTRSTAT_RXREADY) == | |||
- UTRSTAT_RXREADY); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_getc(struct uart_bas *bas, struct mtx *mtx) | |||
-{ | |||
- int utrstat; | |||
- | |||
- utrstat = bus_space_read_1 | |||
- while (!(utrstat & UTRSTAT_RXREADY)) { | |||
- utrstat = bus_space_read_1 | |||
- continue; | |||
- } | |||
- | |||
- return (bus_space_read_1 | |||
-} | |||
- | |||
-static int exynos4210_bus_p | |||
-static int exynos4210_bus_a | |||
-static int exynos4210_bus_f | |||
-static int exynos4210_bus_g | |||
-static int exynos4210_bus_i | |||
-static int exynos4210_bus_i | |||
-static int exynos4210_bus_p | |||
-static int exynos4210_bus_r | |||
-static int exynos4210_bus_s | |||
-static int exynos4210_bus_t | |||
- | |||
-static kobj_method_t exynos4210_metho | |||
- KOBJMETHOD(uart_probe, exynos4210_bus_p | |||
- KOBJMETHOD(uart_attach, exynos4210_bus_a | |||
- KOBJMETHOD(uart_flush, exynos4210_bus_f | |||
- KOBJMETHOD(uart_getsig, exynos4210_bus_g | |||
- KOBJMETHOD(uart_ioctl, exynos4210_bus_i | |||
- KOBJMETHOD(uart_ipend, exynos4210_bus_i | |||
- KOBJMETHOD(uart_param, exynos4210_bus_p | |||
- KOBJMETHOD(uart_receive, exynos4210_bus_r | |||
- KOBJMETHOD(uart_setsig, exynos4210_bus_s | |||
- KOBJMETHOD(uart_transmit, exynos4210_bus_t | |||
- {0, 0 } | |||
-}; | |||
- | |||
-int | |||
-exynos4210_bus_p | |||
-{ | |||
- | |||
- sc->sc_txfifosz = 16; | |||
- sc->sc_rxfifosz = 16; | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_a | |||
-{ | |||
- | |||
- sc->sc_hwiflow = 0; | |||
- sc->sc_hwoflow = 0; | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_t | |||
-{ | |||
- int i; | |||
- int reg; | |||
- | |||
- uart_lock(sc->sc_hwmtx); | |||
- | |||
- for (i = 0; i < sc->sc_txdatasz; i++) { | |||
- exynos4210_putc(&sc->sc_bas, sc->sc_txbuf[i]); | |||
- uart_barrier(&sc->sc_bas); | |||
- } | |||
- | |||
- sc->sc_txbusy = 1; | |||
- | |||
- uart_unlock(sc->sc_hwmtx); | |||
- | |||
- /* unmask TX interrupt */ | |||
- reg = bus_space_read_4 | |||
- reg &= ~(1 << 2); | |||
- bus_space_write_ | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_s | |||
-{ | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_r | |||
-{ | |||
- struct uart_bas *bas; | |||
- | |||
- bas = &sc->sc_bas; | |||
- while (bus_space_read_4 | |||
- SSCOM_UFSTAT) & UFSTAT_RXCOUNT) | |||
- uart_rx_put(sc, uart_getreg(&sc->sc_bas, SSCOM_URXH)); | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_p | |||
- int stopbits, int parity) | |||
-{ | |||
- int error; | |||
- | |||
- if (sc->sc_bas.rclk == 0) | |||
- sc->sc_bas.rclk = DEF_CLK; | |||
- | |||
- KASSERT(sc->sc_bas.rclk != 0, ("exynos4210_init: Invalid rclk")); | |||
- | |||
- uart_lock(sc->sc_hwmtx); | |||
- error = exynos4210_uart_ | |||
- parity); | |||
- uart_unlock(sc->sc_hwmtx); | |||
- | |||
- return (error); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_i | |||
-{ | |||
- uint32_t ints; | |||
- uint32_t txempty, rxready; | |||
- int reg; | |||
- int ipend; | |||
- | |||
- uart_lock(sc->sc_hwmtx); | |||
- ints = bus_space_read_4 | |||
- bus_space_write_ | |||
- | |||
- txempty = (1 << 2); | |||
- rxready = (1 << 0); | |||
- | |||
- ipend = 0; | |||
- if ((ints & txempty) > 0) { | |||
- if (sc->sc_txbusy != 0) | |||
- ipend |= SER_INT_TXIDLE; | |||
- | |||
- /* mask TX interrupt */ | |||
- reg = bus_space_read_4 | |||
- SSCOM_UINTM); | |||
- reg |= (1 << 2); | |||
- bus_space_write_ | |||
- SSCOM_UINTM, reg); | |||
- } | |||
- | |||
- if ((ints & rxready) > 0) { | |||
- ipend |= SER_INT_RXREADY; | |||
- } | |||
- | |||
- uart_unlock(sc->sc_hwmtx); | |||
- return (ipend); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_f | |||
-{ | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_g | |||
-{ | |||
- | |||
- return (0); | |||
-} | |||
- | |||
-static int | |||
-exynos4210_bus_i | |||
-{ | |||
- | |||
- return (EINVAL); | |||
-} | |||
- | |||
-static struct uart_class uart_exynos4210_ | |||
- "exynos4210 class", | |||
- exynos4210_metho | |||
- 1, | |||
- .uc_ops = &uart_exynos4210_ | |||
- .uc_range = 8, | |||
- .uc_rclk = 0, | |||
- .uc_rshift = 0 | |||
-}; | |||
- | |||
-static struct ofw_compat_data compat_data[] = { | |||
- {"exynos", (uintptr_t)&uart_exynos4210_ | |||
- {NULL, (uintptr_t)NULL}, | |||
-}; | |||
-UART_FDT_CLASS_A |
@@ -1,126 +0,0 @@ | |||
-/* $NetBSD: s3c2xx0reg.h,v 1.4 2004/02/12 03:47:29 bsh Exp $ */ | |||
- | |||
-/*- | |||
- * Copyright (c) 2002, 2003 Fujitsu Component Limited | |||
- * Copyright (c) 2002, 2003 Genetec Corporation | |||
- * All rights reserved. | |||
- * | |||
- * Redistribution and use in source and binary forms, with or without | |||
- * modification, are permitted provided that the following conditions | |||
- * are met: | |||
- * 1. Redistributions of source code must retain the above copyright | |||
- * notice, this list of conditions and the following disclaimer. | |||
- * 2. Redistributions in binary form must reproduce the above copyright | |||
- * notice, this list of conditions and the following disclaimer in the | |||
- * documentation and/or other materials provided with the distribution. | |||
- * 3. Neither the name of The Fujitsu Component Limited nor the name of | |||
- * Genetec corporation may not be used to endorse or promote products | |||
- * derived from this software without specific prior written permission. | |||
- * | |||
- * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC | |||
- * CORPORATION ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
- * DISCLAIMED. IN NO EVENT SHALL FUJITSU COMPONENT LIMITED OR GENETEC | |||
- * CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
- * SUCH DAMAGE. | |||
- * | |||
- * $FreeBSD$ | |||
- */ | |||
- | |||
-/* s3c2410-specific registers */ | |||
-#define UMCON_AFC (1 << 4) /* auto flow control */ | |||
-#define UMSTAT_DCTS (1 << 2) /* CTS change */ | |||
-#define ULCON_IR (1 << 6) | |||
-#define ULCON_PARITY_SHI | |||
- | |||
-/* | |||
- * Exynos-specific | |||
- * | |||
- * UFSTAT_TXFULL register differs between Exynos and others. | |||
- * Others have UFSTAT_TXFULL (1 << 9) | |||
- */ | |||
-#define UFSTAT_TXFULL (1 << 24) | |||
- | |||
-#define SSCOM_UINTM 0x038 | |||
-#define SSCOM_UINTP 0x030 | |||
- | |||
-/* common for s3c2800 and s3c24x0 */ | |||
-#define SSCOM_ULCON 0x00 /* UART line control */ | |||
-#define ULCON_PARITY_NON | |||
-#define ULCON_PARITY_ODD | |||
-#define ULCON_PARITY_EVE | |||
-#define ULCON_PARITY_ONE | |||
-#define ULCON_PARITY_ZER | |||
-#define ULCON_STOP (1 << 2) | |||
-#define ULCON_LENGTH_5 0 | |||
-#define ULCON_LENGTH_6 1 | |||
-#define ULCON_LENGTH_7 2 | |||
-#define ULCON_LENGTH_8 3 | |||
-#define SSCOM_UCON 0x04 /* UART control */ | |||
-#define UCON_TXINT_TYPE (1 << 9) /* Tx interrupt. 0=pulse,1=level */ | |||
-#define UCON_TXINT_TYPE_ | |||
-#define UCON_TXINT_TYPE_ | |||
-#define UCON_RXINT_TYPE (1 << 8) /* Rx interrupt */ | |||
-#define UCON_RXINT_TYPE_ | |||
-#define UCON_RXINT_TYPE_ | |||
-#define UCON_TOINT (1 << 7) /* Rx timeout interrupt */ | |||
-#define UCON_ERRINT (1 << 6) /* receive error interrupt */ | |||
-#define UCON_LOOP (1 << 5) /* loopback */ | |||
-#define UCON_SBREAK (1 << 4) /* send break */ | |||
-#define UCON_TXMODE_DISA | |||
-#define UCON_TXMODE_INT (1 << 2) | |||
-#define UCON_TXMODE_DMA (2 << 2) | |||
-#define UCON_TXMODE_MASK | |||
-#define UCON_RXMODE_DISA | |||
-#define UCON_RXMODE_INT (1 << 0) | |||
-#define UCON_RXMODE_DMA (2 << 0) | |||
-#define UCON_RXMODE_MASK | |||
-#define SSCOM_UFCON 0x08 /* FIFO control */ | |||
-#define UFCON_TXTRIGGER_ | |||
-#define UFCON_TXTRIGGER_ | |||
-#define UFCON_TXTRIGGER_ | |||
-#define UFCON_TXTRIGGER_ | |||
-#define UFCON_RXTRIGGER_ | |||
-#define UFCON_RXTRIGGER_ | |||
-#define UFCON_RXTRIGGER_ | |||
-#define UFCON_RXTRIGGER_ | |||
-#define UFCON_TXFIFO_RES | |||
-#define UFCON_RXFIFO_RES | |||
-#define UFCON_FIFO_ENABL | |||
-#define SSCOM_UMCON 0x0c /* MODEM control */ | |||
-#define UMCON_RTS (1 << 0) /* Request to send */ | |||
-#define SSCOM_UTRSTAT 0x10 /* Status register */ | |||
-#define UTRSTAT_TXSHIFTE | |||
-#define UTRSTAT_TXEMPTY (1 << 1) /* TX fifo or buffer empty */ | |||
-#define UTRSTAT_RXREADY (1 << 0) /* RX fifo or buffer is not empty */ | |||
-#define SSCOM_UERSTAT 0x14 /* Error status register */ | |||
-#define UERSTAT_BREAK (1 << 3) /* Break signal, not 2410 */ | |||
-#define UERSTAT_FRAME (1 << 2) /* Frame error */ | |||
-#define UERSTAT_PARITY (1 << 1) /* Parity error, not 2410 */ | |||
-#define UERSTAT_OVERRUN (1 << 0) /* Overrun */ | |||
-#define UERSTAT_ALL_ERRO | |||
- (UERSTAT_OVERRUN|UERSTAT_BREAK|UERSTAT_FRAME|UERSTAT_PARITY) | |||
-#define SSCOM_UFSTAT 0x18 /* Fifo status register */ | |||
-#define UFSTAT_RXFULL (1 <<8) /* Rx fifo full */ | |||
-#define UFSTAT_TXCOUNT_S | |||
-#define UFSTAT_TXCOUNT (0x0f << UFSTAT_TXCOUNT_S | |||
-#define UFSTAT_RXCOUNT_S | |||
-#define UFSTAT_RXCOUNT (0x0f << UFSTAT_RXCOUNT_S | |||
-#define SSCOM_UMSTAT 0x1c /* Modem status register */ | |||
-#define UMSTAT_CTS (1 << 0) /* Clear to send */ | |||
-#if _BYTE_ORDER == _LITTLE_ENDIAN | |||
-#define SSCOM_UTXH 0x20 /* Transmit data register */ | |||
-#define SSCOM_URXH 0x24 /* Receive data register */ | |||
-#else | |||
-#define SSCOM_UTXH 0x23 /* Transmit data register */ | |||
-#define SSCOM_URXH 0x27 /* Receive data register */ | |||
-#endif | |||
-#define SSCOM_UBRDIV 0x28 /* baud-reate divisor */ | |||
-#define SSCOM_SIZE 0x2c |
@@ -1,23 +0,0 @@ | |||
-# $FreeBSD$ | |||
- | |||
-arm/samsung/exynos/exynos5_mct.c standard | |||
-arm/samsung/exynos/exynos5_mp.c optional smp | |||
-arm/samsung/exynos/exynos5_machdep.c standard | |||
-arm/samsung/exynos/exynos5_combiner | |||
-arm/samsung/exynos/exynos5_pad.c optional gpio | |||
-arm/samsung/exynos/exynos_uart.c optional uart | |||
-arm/samsung/exynos/exynos5_ehci.c optional ehci | |||
-arm/samsung/exynos/exynos5_xhci.c optional xhci | |||
-arm/samsung/exynos/exynos5_fimd.c optional vt | |||
-arm/samsung/exynos/exynos5_i2c.c optional iicbus | |||
-arm/samsung/exynos/exynos5_usb_phy.c standard | |||
-arm/samsung/exynos/exynos5_pmu.c standard | |||
-arm/samsung/exynos/exynos5_spi.c optional exynos_spi | |||
- | |||
-# chromebook drivers | |||
-arm/samsung/exynos/chrome_ec.c optional chrome_ec_i2c | |||
-arm/samsung/exynos/chrome_ec_spi.c optional chrome_ec_spi | |||
-arm/samsung/exynos/chrome_kb.c optional chrome_kb | |||
- | |||
-dev/mmc/host/dwmmc.c optional dwmmc | |||
-dev/mmc/host/dwmmc_samsung.c optional dwmmc |
@@ -1,7 +0,0 @@ | |||
-# $FreeBSD$ | |||
- | |||
-cpu CPU_CORTEXA | |||
-machine arm armv7 | |||
-makeoptions CONF_CFLAGS="-march=armv7a" | |||
- | |||
-files "../samsung/exynos/files.exynos5" |
@@ -1,7 +0,0 @@ | |||
-# $FreeBSD$ | |||
- | |||
-cpu CPU_CORTEXA | |||
-machine arm armv7 | |||
-makeoptions CONF_CFLAGS="-march=armv7a" | |||
- | |||
-files "../samsung/exynos/files.exynos5" |
@@ -37,30 +37,30 @@ | |||
#define MAX_ERRNO 4095 | #define MAX_ERRNO 4095 | ||
-#define IS_ERR_VALUE(x) unlikely((x) >= ( | +#define IS_ERR_VALUE(x) unlikely((x) >= (uintptr_t)-MAX_ERRNO) | ||
static inline void * | static inline void * | ||
ERR_PTR(long error) | ERR_PTR(long error) | ||
{ | { | ||
- return (void *)error; | + return (void *)(intptr_t)error; | ||
} | } | ||
static inline long | static inline long | ||
PTR_ERR(const void *ptr) | PTR_ERR(const void *ptr) | ||
{ | { | ||
- return ( | + return (intptr_t)ptr; | ||
} | } | ||
-static inline | +static inline bool | ||
IS_ERR(const void *ptr) | IS_ERR(const void *ptr) | ||
{ | { | ||
- return IS_ERR_VALUE(( | + return IS_ERR_VALUE((uintptr_t)ptr); | ||
} | } | ||
-static inline | +static inline bool | ||
IS_ERR_OR_NULL(const void *ptr) | IS_ERR_OR_NULL(const void *ptr) | ||
{ | { | ||
- return !ptr || IS_ERR_VALUE(( | + return !ptr || IS_ERR_VALUE((uintptr_t)ptr); | ||
} | } | ||
static inline void * | static inline void * |
@@ -184,8 +184,9 @@ NORMAL_M= ${AWK} -f $S/tools/makeobj | |||
${CC} -c ${CFLAGS} ${WERROR} ${PROF} ${.PREFIX}.c | ${CC} -c ${CFLAGS} ${WERROR} ${PROF} ${.PREFIX}.c | ||
NORMAL_FW= uudecode -o ${.TARGET} ${.ALLSRC} | NORMAL_FW= uudecode -o ${.TARGET} ${.ALLSRC} | ||
-NORMAL_FWO= ${LD} -b binary --no-warn-mismatch -d -warn-common -r \ | +NORMAL_FWO= ${CC:N${CCACHE_BIN}} -c ${ASM_CFLAGS} ${WERROR} -o ${.TARGET} \ | ||
- -m ${LD_EMULATION} -o ${.TARGET} ${.ALLSRC:M*.fw} | + $S/kern/firmw.S -DFIRMW_FILE="${.ALLSRC:M*.fw}" \ | ||
+ -DFIRMW_SYMBOL="${.ALLSRC:M*.fw:C/[-.\/]/_/g}" | |||
# for ZSTD in the kernel (include zstd/lib/freebsd before other CFLAGS) | # for ZSTD in the kernel (include zstd/lib/freebsd before other CFLAGS) | ||
ZSTD_C= ${CC} -c -DZSTD_HEAPMODE=1 -I$S/contrib/zstd/lib/freebsd ${CFLAGS} -I$S/contrib/zstd/lib -I$S/contrib/zstd/lib/common ${WERROR} -Wno-inline -Wno-missing-prototypes ${PROF} -U__BMI__ ${.IMPSRC} | ZSTD_C= ${CC} -c -DZSTD_HEAPMODE=1 -I$S/contrib/zstd/lib/freebsd ${CFLAGS} -I$S/contrib/zstd/lib -I$S/contrib/zstd/lib/common ${WERROR} -Wno-inline -Wno-missing-prototypes ${PROF} -U__BMI__ ${.IMPSRC} |
@@ -191,19 +191,13 @@ SRCS+= ${KMOD:S/$/.c/} | |||
CLEANFILES+= ${KMOD:S/$/.c/} | CLEANFILES+= ${KMOD:S/$/.c/} | ||
.for _firmw in ${FIRMWS} | .for _firmw in ${FIRMWS} | ||
-${_firmw:C/\:.*$/.fwo/:T}: ${_firmw:C/\:.*$//} | +${_firmw:C/\:.*$/.fwo/:T}: ${_firmw:C/\:.*$//} ${SYSDIR}/kern/firmw.S | ||
@${ECHO} ${_firmw:C/\:.*$//} ${.ALLSRC:M*${_firmw:C/\:.*$//}} | @${ECHO} ${_firmw:C/\:.*$//} ${.ALLSRC:M*${_firmw:C/\:.*$//}} | ||
- @if [ -e ${_firmw:C/\:.*$//} ]; then \ | + ${CC:N${CCACHE_BIN}} -c -x assembler-with-cpp -DLOCORE \ | ||
- ${LD} -b binary --no-warn-mismatch ${_LDFLAGS} \ | + ${CFLAGS} ${WERROR} \ | ||
- -m ${LD_EMULATION} -r -d \ | + -DFIRMW_FILE="${.ALLSRC:M*${_firmw:C/\:.*$//}}" \ | ||
- -o ${.TARGET} ${_firmw:C/\:.*$//}; \ | + -DFIRMW_SYMBOL="${_firmw:C/\:.*$//:C/[-.\/]/_/g}" \ | ||
- else \ | + ${SYSDIR}/kern/firmw.S -o ${.TARGET} | ||
- ln -s ${.ALLSRC:M*${_firmw:C/\:.*$//}} ${_firmw:C/\:.*$//}; \ | |||
- ${LD} -b binary --no-warn-mismatch ${_LDFLAGS} \ | |||
- -m ${LD_EMULATION} -r -d \ | |||
- -o ${.TARGET} ${_firmw:C/\:.*$//}; \ | |||
- rm ${_firmw:C/\:.*$//}; \ | |||
- fi | |||
OBJS+= ${_firmw:C/\:.*$/.fwo/:T} | OBJS+= ${_firmw:C/\:.*$/.fwo/:T} | ||
.endfor | .endfor |
@@ -152,6 +152,10 @@ ofw_spibus_attac | |||
continue; | continue; | ||
} | } | ||
childdev = device_add_child | childdev = device_add_child | ||
+ | |||
+ resource_list_in | |||
+ ofw_bus_intr_to_ | |||
+ &dinfo->opd_dinfo.rl, NULL); | |||
device_set_ivars | device_set_ivars | ||
} | } | ||
@@ -198,6 +202,15 @@ ofw_spibus_get_d | |||
return (&dinfo->opd_obdinfo); | return (&dinfo->opd_obdinfo); | ||
} | } | ||
+static struct resource_list * | |||
+ofw_spibus_get_r | |||
+{ | |||
+ struct spibus_ivar *devi; | |||
+ | |||
+ devi = SPIBUS_IVAR(child); | |||
+ return (&devi->rl); | |||
+} | |||
+ | |||
static device_method_t ofw_spibus_metho | static device_method_t ofw_spibus_metho | ||
/* Device interface */ | /* Device interface */ | ||
DEVMETHOD(device_probe, ofw_spibus_probe | DEVMETHOD(device_probe, ofw_spibus_probe | ||
@@ -206,6 +219,7 @@ static device_method_t ofw_spibus_metho | |||
/* Bus interface */ | /* Bus interface */ | ||
DEVMETHOD(bus_child_pnpinf | DEVMETHOD(bus_child_pnpinf | ||
DEVMETHOD(bus_add_child, ofw_spibus_add_c | DEVMETHOD(bus_add_child, ofw_spibus_add_c | ||
+ DEVMETHOD(bus_get_resource | |||
/* ofw_bus interface */ | /* ofw_bus interface */ | ||
DEVMETHOD(ofw_bus_get_devi | DEVMETHOD(ofw_bus_get_devi |
@@ -101,6 +101,8 @@ spibus_print_chi | |||
retval += bus_print_child_ | retval += bus_print_child_ | ||
retval += printf(" at cs %d", devi->cs); | retval += printf(" at cs %d", devi->cs); | ||
retval += printf(" mode %d", devi->mode); | retval += printf(" mode %d", devi->mode); | ||
+ retval += resource_list_pr | |||
+ SYS_RES_IRQ, "%jd"); | |||
retval += bus_print_child_ | retval += bus_print_child_ | ||
return (retval); | return (retval); | ||
@@ -202,6 +204,7 @@ spibus_add_child | |||
device_delete_ch | device_delete_ch | ||
return (0); | return (0); | ||
} | } | ||
+ resource_list_in | |||
device_set_ivars | device_set_ivars | ||
return (child); | return (child); | ||
} | } | ||
@@ -210,6 +213,7 @@ static void | |||
spibus_hinted_ch | spibus_hinted_ch | ||
{ | { | ||
device_t child; | device_t child; | ||
+ int irq; | |||
struct spibus_ivar *devi; | struct spibus_ivar *devi; | ||
child = BUS_ADD_CHILD(bus, 0, dname, dunit); | child = BUS_ADD_CHILD(bus, 0, dname, dunit); | ||
@@ -218,6 +222,20 @@ spibus_hinted_ch | |||
resource_int_val | resource_int_val | ||
resource_int_val | resource_int_val | ||
resource_int_val | resource_int_val | ||
+ if (resource_int_val | |||
+ if (bus_set_resource | |||
+ device_printf(bus, | |||
+ "Warning: bus_set_resource | |||
+ } | |||
+} | |||
+ | |||
+static struct resource_list * | |||
+spibus_get_resou | |||
+{ | |||
+ struct spibus_ivar *devi; | |||
+ | |||
+ devi = SPIBUS_IVAR(child); | |||
+ return (&devi->rl); | |||
} | } | ||
static int | static int | ||
@@ -236,6 +254,17 @@ static device_method_t spibus_methods[] | |||
DEVMETHOD(device_resume, spibus_resume), | DEVMETHOD(device_resume, spibus_resume), | ||
/* Bus interface */ | /* Bus interface */ | ||
+ DEVMETHOD(bus_setup_intr, bus_generic_setu | |||
+ DEVMETHOD(bus_teardown_int | |||
+ DEVMETHOD(bus_release_reso | |||
+ DEVMETHOD(bus_activate_res | |||
+ DEVMETHOD(bus_deactivate_r | |||
+ DEVMETHOD(bus_adjust_resou | |||
+ DEVMETHOD(bus_alloc_resour | |||
+ DEVMETHOD(bus_get_resource | |||
+ DEVMETHOD(bus_set_resource | |||
+ DEVMETHOD(bus_get_resource | |||
+ | |||
DEVMETHOD(bus_add_child, spibus_add_child | DEVMETHOD(bus_add_child, spibus_add_child | ||
DEVMETHOD(bus_print_child, | DEVMETHOD(bus_print_child, | ||
DEVMETHOD(bus_probe_nomatc | DEVMETHOD(bus_probe_nomatc |
@@ -43,6 +43,7 @@ struct spibus_ivar | |||
uint32_t cs; | uint32_t cs; | ||
uint32_t mode; | uint32_t mode; | ||
uint32_t clock; | uint32_t clock; | ||
+ struct resource_list rl; | |||
}; | }; | ||
#define SPIBUS_CS_HIGH (1U << 31) | #define SPIBUS_CS_HIGH (1U << 31) |
@@ -90,8 +90,7 @@ | |||
#include <dev/usb/controller/ehcireg.h> | #include <dev/usb/controller/ehcireg.h> | ||
#define EHCI_BUS2SC(bus) \ | #define EHCI_BUS2SC(bus) \ | ||
- ((ehci_softc_t *)(((uint8_t *)(bus)) - \ | + __containerof(bus, ehci_softc_t, sc_bus) | ||
- ((uint8_t *)&(((ehci_softc_t *)0)->sc_bus)))) | |||
#ifdef USB_DEBUG | #ifdef USB_DEBUG | ||
static int ehcidebug = 0; | static int ehcidebug = 0; |
@@ -79,8 +79,7 @@ | |||
#include <dev/usb/controller/ohcireg.h> | #include <dev/usb/controller/ohcireg.h> | ||
#define OHCI_BUS2SC(bus) \ | #define OHCI_BUS2SC(bus) \ | ||
- ((ohci_softc_t *)(((uint8_t *)(bus)) - \ | + __containerof(bus, ohci_softc_t, sc_bus) | ||
- ((uint8_t *)&(((ohci_softc_t *)0)->sc_bus)))) | |||
#ifdef USB_DEBUG | #ifdef USB_DEBUG | ||
static int ohcidebug = 0; | static int ohcidebug = 0; |
@@ -83,8 +83,7 @@ | |||
#define alt_next next | #define alt_next next | ||
#define UHCI_BUS2SC(bus) \ | #define UHCI_BUS2SC(bus) \ | ||
- ((uhci_softc_t *)(((uint8_t *)(bus)) - \ | + __containerof(bus, uhci_softc_t, sc_bus) | ||
- ((uint8_t *)&(((uhci_softc_t *)0)->sc_bus)))) | |||
#ifdef USB_DEBUG | #ifdef USB_DEBUG | ||
static int uhcidebug = 0; | static int uhcidebug = 0; |
@@ -86,8 +86,7 @@ | |||
#include <dev/usb/controller/xhcireg.h> | #include <dev/usb/controller/xhcireg.h> | ||
#define XHCI_BUS2SC(bus) \ | #define XHCI_BUS2SC(bus) \ | ||
- ((struct xhci_softc *)(((uint8_t *)(bus)) - \ | + __containerof(bus, struct xhci_softc, sc_bus) | ||
- ((uint8_t *)&(((struct xhci_softc *)0)->sc_bus)))) | |||
static SYSCTL_NODE(_hw_usb, OID_AUTO, xhci, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | static SYSCTL_NODE(_hw_usb, OID_AUTO, xhci, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | ||
"USB XHCI"); | "USB XHCI"); |
@@ -153,9 +153,7 @@ struct usb_done_msg { | |||
}; | }; | ||
#define USB_DMATAG_TO_XR | #define USB_DMATAG_TO_XR | ||
- ((struct usb_xfer_root *)( \ | + __containerof(dpt, struct usb_xfer_root, dma_parent_tag) | ||
- ((uint8_t *)(dpt)) - \ | |||
- ((uint8_t *)&((struct usb_xfer_root *)0)->dma_parent_tag))) | |||
/* | /* | ||
* The following structure is used to keep information about memory | * The following structure is used to keep information about memory |
@@ -1903,7 +1903,7 @@ nfsv4_loadattr(s | |||
savuid = p->p_cred->p_ruid; | savuid = p->p_cred->p_ruid; | ||
p->p_cred->p_ruid = cred->cr_uid; | p->p_cred->p_ruid = cred->cr_uid; | ||
if (!VFS_QUOTACTL(vp->v_mount,QCMD(Q_GETQUOTA, | if (!VFS_QUOTACTL(vp->v_mount,QCMD(Q_GETQUOTA, | ||
- USRQUOTA), cred->cr_uid, | + USRQUOTA), cred->cr_uid, &dqb)) | ||
freenum = min(dqb.dqb_bhardlimit, freenum); | freenum = min(dqb.dqb_bhardlimit, freenum); | ||
p->p_cred->p_ruid = savuid; | p->p_cred->p_ruid = savuid; | ||
#endif /* QUOTA */ | #endif /* QUOTA */ | ||
@@ -1932,7 +1932,7 @@ nfsv4_loadattr(s | |||
savuid = p->p_cred->p_ruid; | savuid = p->p_cred->p_ruid; | ||
p->p_cred->p_ruid = cred->cr_uid; | p->p_cred->p_ruid = cred->cr_uid; | ||
if (!VFS_QUOTACTL(vp->v_mount,QCMD(Q_GETQUOTA, | if (!VFS_QUOTACTL(vp->v_mount,QCMD(Q_GETQUOTA, | ||
- USRQUOTA), cred->cr_uid, | + USRQUOTA), cred->cr_uid, &dqb)) | ||
freenum = min(dqb.dqb_bsoftlimit, freenum); | freenum = min(dqb.dqb_bsoftlimit, freenum); | ||
p->p_cred->p_ruid = savuid; | p->p_cred->p_ruid = savuid; | ||
#endif /* QUOTA */ | #endif /* QUOTA */ | ||
@@ -1958,7 +1958,7 @@ nfsv4_loadattr(s | |||
savuid = p->p_cred->p_ruid; | savuid = p->p_cred->p_ruid; | ||
p->p_cred->p_ruid = cred->cr_uid; | p->p_cred->p_ruid = cred->cr_uid; | ||
if (!VFS_QUOTACTL(vp->v_mount,QCMD(Q_GETQUOTA, | if (!VFS_QUOTACTL(vp->v_mount,QCMD(Q_GETQUOTA, | ||
- USRQUOTA), cred->cr_uid, | + USRQUOTA), cred->cr_uid, &dqb)) | ||
freenum = dqb.dqb_curblocks; | freenum = dqb.dqb_curblocks; | ||
p->p_cred->p_ruid = savuid; | p->p_cred->p_ruid = savuid; | ||
#endif /* QUOTA */ | #endif /* QUOTA */ | ||
@@ -2704,7 +2704,7 @@ nfsv4_fillattr(s | |||
savuid = p->p_cred->p_ruid; | savuid = p->p_cred->p_ruid; | ||
p->p_cred->p_ruid = cred->cr_uid; | p->p_cred->p_ruid = cred->cr_uid; | ||
if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQU | if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQU | ||
- cred->cr_uid, | + cred->cr_uid, &dqb)) | ||
freenum = min(dqb.dqb_isoftlimit-dqb.dqb_curinodes, | freenum = min(dqb.dqb_isoftlimit-dqb.dqb_curinodes, | ||
freenum); | freenum); | ||
p->p_cred->p_ruid = savuid; | p->p_cred->p_ruid = savuid; | ||
@@ -2811,7 +2811,7 @@ nfsv4_fillattr(s | |||
savuid = p->p_cred->p_ruid; | savuid = p->p_cred->p_ruid; | ||
p->p_cred->p_ruid = cred->cr_uid; | p->p_cred->p_ruid = cred->cr_uid; | ||
if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQU | if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQU | ||
- cred->cr_uid, | + cred->cr_uid, &dqb)) | ||
freenum = min(dqb.dqb_bhardlimit, freenum); | freenum = min(dqb.dqb_bhardlimit, freenum); | ||
p->p_cred->p_ruid = savuid; | p->p_cred->p_ruid = savuid; | ||
#endif /* QUOTA */ | #endif /* QUOTA */ | ||
@@ -2835,7 +2835,7 @@ nfsv4_fillattr(s | |||
savuid = p->p_cred->p_ruid; | savuid = p->p_cred->p_ruid; | ||
p->p_cred->p_ruid = cred->cr_uid; | p->p_cred->p_ruid = cred->cr_uid; | ||
if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQU | if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQU | ||
- cred->cr_uid, | + cred->cr_uid, &dqb)) | ||
freenum = min(dqb.dqb_bsoftlimit, freenum); | freenum = min(dqb.dqb_bsoftlimit, freenum); | ||
p->p_cred->p_ruid = savuid; | p->p_cred->p_ruid = savuid; | ||
#endif /* QUOTA */ | #endif /* QUOTA */ | ||
@@ -2856,7 +2856,7 @@ nfsv4_fillattr(s | |||
savuid = p->p_cred->p_ruid; | savuid = p->p_cred->p_ruid; | ||
p->p_cred->p_ruid = cred->cr_uid; | p->p_cred->p_ruid = cred->cr_uid; | ||
if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQU | if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQU | ||
- cred->cr_uid, | + cred->cr_uid, &dqb)) | ||
freenum = dqb.dqb_curblocks; | freenum = dqb.dqb_curblocks; | ||
p->p_cred->p_ruid = savuid; | p->p_cred->p_ruid = savuid; | ||
#endif /* QUOTA */ | #endif /* QUOTA */ |
@@ -1,6 +1,12 @@ | |||
/*- | /*- | ||
- * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> | + * SPDX-License-Identifier: BSD-2-Clause | ||
- * All rights reserved. | + * | ||
+ * Copyright (c) 2020 John Baldwin <jhb@FreeBSD.org> | |||
+ * | |||
+ * This software was developed by SRI International and the University of | |||
+ * Cambridge Computer Laboratory (Department of Computer Science and | |||
+ * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the | |||
+ * DARPA SSITH research programme. | |||
* | * | ||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||
@@ -26,13 +32,18 @@ | |||
* $FreeBSD$ | * $FreeBSD$ | ||
*/ | */ | ||
-#define EC_CMD_HELLO 0x01 | +#include <sys/cdefs.h> | ||
-#define EC_CMD_GET_VERSI | + | ||
-#define EC_CMD_MKBP_STAT | +#define FIRMW_START(S) __CONCAT(_binary_, __CONCAT(S, _start)) | ||
-#define EC_CMD_VERSION0 0xdc | +#define FIRMW_END(S) __CONCAT(_binary_, __CONCAT(S, _end)) | ||
-#define EC_CMD_RESEND_RE | |||
-#define EC_CMD_GET_COMMS | |||
-int ec_command(uint8_t cmd, uint8_t *dout, uint8_t dout_len, | + .section rodata, "a", %progbits | ||
- uint8_t *dinp, uint8_t dinp_len); | + .globl FIRMW_START(FIRMW_SYMBOL) | ||
-int ec_hello(void); | + .type FIRMW_START(FIRMW_SYMBOL), %object | ||
+FIRMW_START(FIRMW_SYMBOL): | |||
+ .incbin __XSTRING(FIRMW_FILE) | |||
+ .size FIRMW_START(FIRMW_SYMBOL), . - FIRMW_START(FIRMW_SYMBOL) | |||
+ .globl FIRMW_END(FIRMW_SYMBOL) | |||
+ .type FIRMW_END(FIRMW_SYMBOL), %object | |||
+FIRMW_END(FIRMW_SYMBOL): | |||
+ .size FIRMW_END(FIRMW_SYMBOL), . - FIRMW_END(FIRMW_SYMBOL) |
@@ -107,7 +107,7 @@ __read_mostly uma_zone_t pwd_zone; | |||
VFS_SMR_DECLARE; | VFS_SMR_DECLARE; | ||
static int closefp(struct filedesc *fdp, int fd, struct file *fp, | static int closefp(struct filedesc *fdp, int fd, struct file *fp, | ||
- struct thread *td, | + struct thread *td, bool holdleaders, bool audit); | ||
static int fd_first_free(struct filedesc *fdp, int low, int size); | static int fd_first_free(struct filedesc *fdp, int low, int size); | ||
static void fdgrowtable(struct filedesc *fdp, int nfd); | static void fdgrowtable(struct filedesc *fdp, int nfd); | ||
static void fdgrowtable_exp(struct filedesc *fdp, int nfd); | static void fdgrowtable_exp(struct filedesc *fdp, int nfd); | ||
@@ -307,6 +307,7 @@ fdfree(struct filedesc *fdp, int fd) | |||
{ | { | ||
struct filedescent *fde; | struct filedescent *fde; | ||
+ FILEDESC_XLOCK_A | |||
fde = &fdp->fd_ofiles[fd]; | fde = &fdp->fd_ofiles[fd]; | ||
#ifdef CAPABILITIES | #ifdef CAPABILITIES | ||
seqc_write_begin | seqc_write_begin | ||
@@ -998,7 +999,7 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new) | |||
error = 0; | error = 0; | ||
if (delfp != NULL) { | if (delfp != NULL) { | ||
- (void) closefp(fdp, new, delfp, td, | + (void) closefp(fdp, new, delfp, td, true, false); | ||
FILEDESC_UNLOCK_ | FILEDESC_UNLOCK_ | ||
} else { | } else { | ||
unlock: | unlock: | ||
@@ -1239,29 +1240,14 @@ fgetown(struct sigio **sigiop) | |||
return (pgid); | return (pgid); | ||
} | } | ||
-/* | |||
- * Function drops the filedesc lock on return. | |||
- */ | |||
static int | static int | ||
- | +closefp_impl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td, | ||
- int holdleaders) | + bool audit) | ||
{ | { | ||
int error; | int error; | ||
FILEDESC_XLOCK_A | FILEDESC_XLOCK_A | ||
- if (holdleaders) { | |||
- if (td->td_proc->p_fdtol != NULL) { | |||
- /* | |||
- * Ask fdfree() to sleep to ensure that all relevant | |||
- * process leaders can be traversed in closef(). | |||
- */ | |||
- fdp->fd_holdleadersco | |||
- } else { | |||
- holdleaders = 0; | |||
- } | |||
- } | |||
- | |||
/* | /* | ||
* We now hold the fp reference that used to be owned by the | * We now hold the fp reference that used to be owned by the | ||
* descriptor array. We have to unlock the FILEDESC *AFTER* | * descriptor array. We have to unlock the FILEDESC *AFTER* | ||
@@ -1278,6 +1264,10 @@ closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td, | |||
mq_fdclose(td, fd, fp); | mq_fdclose(td, fd, fp); | ||
FILEDESC_XUNLOCK | FILEDESC_XUNLOCK | ||
+#ifdef AUDIT | |||
+ if (AUDITING_TD(td) && audit) | |||
+ audit_sysclose(td, fd, fp); | |||
+#endif | |||
error = closef(fp, td); | error = closef(fp, td); | ||
/* | /* | ||
@@ -1288,6 +1278,30 @@ closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td, | |||
if (error == ERESTART) | if (error == ERESTART) | ||
error = EINTR; | error = EINTR; | ||
+ return (error); | |||
+} | |||
+ | |||
+static int | |||
+closefp_hl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td, | |||
+ bool holdleaders, bool audit) | |||
+{ | |||
+ int error; | |||
+ | |||
+ FILEDESC_XLOCK_A | |||
+ | |||
+ if (holdleaders) { | |||
+ if (td->td_proc->p_fdtol != NULL) { | |||
+ /* | |||
+ * Ask fdfree() to sleep to ensure that all relevant | |||
+ * process leaders can be traversed in closef(). | |||
+ */ | |||
+ fdp->fd_holdleadersco | |||
+ } else { | |||
+ holdleaders = false; | |||
+ } | |||
+ } | |||
+ | |||
+ error = closefp_impl(fdp, fd, fp, td, audit); | |||
if (holdleaders) { | if (holdleaders) { | ||
FILEDESC_XLOCK(fdp); | FILEDESC_XLOCK(fdp); | ||
fdp->fd_holdleadersco | fdp->fd_holdleadersco | ||
@@ -1301,6 +1315,20 @@ closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td, | |||
return (error); | return (error); | ||
} | } | ||
+static int | |||
+closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td, | |||
+ bool holdleaders, bool audit) | |||
+{ | |||
+ | |||
+ FILEDESC_XLOCK_A | |||
+ | |||
+ if (__predict_false(td->td_proc->p_fdtol != NULL)) { | |||
+ return (closefp_hl(fdp, fd, fp, td, holdleaders, audit)); | |||
+ } else { | |||
+ return (closefp_impl(fdp, fd, fp, td, audit)); | |||
+ } | |||
+} | |||
+ | |||
/* | /* | ||
* Close a file descriptor. | * Close a file descriptor. | ||
*/ | */ | ||
@@ -1325,8 +1353,6 @@ kern_close(struc | |||
fdp = td->td_proc->p_fd; | fdp = td->td_proc->p_fd; | ||
- AUDIT_SYSCLOSE(td, fd); | |||
- | |||
FILEDESC_XLOCK(fdp); | FILEDESC_XLOCK(fdp); | ||
if ((fp = fget_locked(fdp, fd)) == NULL) { | if ((fp = fget_locked(fdp, fd)) == NULL) { | ||
FILEDESC_XUNLOCK | FILEDESC_XUNLOCK | ||
@@ -1335,18 +1361,16 @@ kern_close(struc | |||
fdfree(fdp, fd); | fdfree(fdp, fd); | ||
/* closefp() drops the FILEDESC lock for us. */ | /* closefp() drops the FILEDESC lock for us. */ | ||
- return (closefp(fdp, fd, fp, td, | + return (closefp(fdp, fd, fp, td, true, true)); | ||
} | } | ||
int | int | ||
kern_close_range | kern_close_range | ||
{ | { | ||
struct filedesc *fdp; | struct filedesc *fdp; | ||
- int fd, ret, lastfile; | + const struct fdescenttbl *fdt; | ||
- | + struct file *fp; | ||
- ret = 0; | + int fd; | ||
- fdp = td->td_proc->p_fd; | |||
- FILEDESC_SLOCK(fdp); | |||
/* | /* | ||
* Check this prior to clamping; closefrom(3) with only fd 0, 1, and 2 | * Check this prior to clamping; closefrom(3) with only fd 0, 1, and 2 | ||
@@ -1355,30 +1379,36 @@ kern_close_range | |||
* be a usage error as all fd above 3 are in-fact already closed. | * be a usage error as all fd above 3 are in-fact already closed. | ||
*/ | */ | ||
if (highfd < lowfd) { | if (highfd < lowfd) { | ||
- | + return (EINVAL); | ||
- goto out; | |||
} | } | ||
- /* | + fdp = td->td_proc->p_fd; | ||
- * If lastfile == -1, we're dealing with either a fresh file | + FILEDESC_XLOCK(fdp); | ||
- * table or one in which every fd has been closed. Just return | + fdt = atomic_load_ptr(&fdp->fd_files); | ||
- * successful; there's nothing left to do. | + highfd = MIN(highfd, fdt->fdt_nfiles - 1); | ||
- */ | + fd = lowfd; | ||
- lastfile = fdlastfile(fdp); | + if (__predict_false(fd > highfd)) { | ||
- if (lastfile == -1) | + goto out_locked; | ||
- goto out; | + } | ||
- /* Clamped to [lowfd, lastfile] */ | + for (;;) { | ||
- highfd = MIN(highfd, lastfile); | + fp = fdt->fdt_ofiles[fd].fde_file; | ||
- for (fd = lowfd; fd <= highfd; fd++) { | + if (fp == NULL) { | ||
- if (fdp->fd_ofiles[fd].fde_file != NULL) { | + if (fd == highfd) | ||
- FILEDESC_SUNLOCK | + goto out_locked; | ||
- (void)kern_close(td, fd); | + } else { | ||
- FILEDESC_SLOCK(fdp); | + fdfree(fdp, fd); | ||
+ (void) closefp(fdp, fd, fp, td, true, true); | |||
+ if (fd == highfd) | |||
+ goto out_unlocked; | |||
+ FILEDESC_XLOCK(fdp); | |||
+ fdt = atomic_load_ptr(&fdp->fd_files); | |||
} | } | ||
+ fd++; | |||
} | } | ||
-out: | +out_locked: | ||
- | + FILEDESC_XUNLOCK(fdp); | ||
- return (ret); | +out_unlocked: | ||
+ return (0); | |||
} | } | ||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||
@@ -2649,7 +2679,7 @@ fdcloseexec(stru | |||
(fde->fde_flags & UF_EXCLOSE))) { | (fde->fde_flags & UF_EXCLOSE))) { | ||
FILEDESC_XLOCK(fdp); | FILEDESC_XLOCK(fdp); | ||
fdfree(fdp, i); | fdfree(fdp, i); | ||
- (void) closefp(fdp, i, fp, td, | + (void) closefp(fdp, i, fp, td, false, false); | ||
FILEDESC_UNLOCK_ | FILEDESC_UNLOCK_ | ||
} | } | ||
} | } |
@@ -1474,6 +1474,7 @@ void | |||
tty_signal_sessl | tty_signal_sessl | ||
{ | { | ||
struct proc *p; | struct proc *p; | ||
+ struct session *s; | |||
tty_assert_locke | tty_assert_locke | ||
MPASS(sig >= 1 && sig < NSIG); | MPASS(sig >= 1 && sig < NSIG); | ||
@@ -1482,8 +1483,14 @@ tty_signal_sessl | |||
tp->t_flags &= ~TF_STOPPED; | tp->t_flags &= ~TF_STOPPED; | ||
tp->t_termios.c_lflag &= ~FLUSHO; | tp->t_termios.c_lflag &= ~FLUSHO; | ||
- if (tp->t_session != NULL && tp->t_session->s_leader != NULL) { | + /* | ||
- p = tp->t_session->s_leader; | + * Load s_leader exactly once to avoid race where s_leader is | ||
+ * set to NULL by a concurrent invocation of killjobc() by the | |||
+ * session leader. Note that we are not holding t_session's | |||
+ * lock for the read. | |||
+ */ | |||
+ if ((s = tp->t_session) != NULL && | |||
+ (p = atomic_load_ptr(&s->s_leader)) != NULL) { | |||
PROC_LOCK(p); | PROC_LOCK(p); | ||
kern_psignal(p, sig); | kern_psignal(p, sig); | ||
PROC_UNLOCK(p); | PROC_UNLOCK(p); |
@@ -987,6 +987,8 @@ ngs_rcvmsg(node_ | |||
m_freem(m); | m_freem(m); | ||
return (ENOBUFS); | return (ENOBUFS); | ||
} | } | ||
+ | |||
+ /* sorwakeup_locked | |||
sorwakeup_locked | sorwakeup_locked | ||
return (error); | return (error); | ||
@@ -1025,12 +1027,17 @@ ngs_rcvdata(hook | |||
addr->sg_data[addrlen] = '\0'; | addr->sg_data[addrlen] = '\0'; | ||
/* Try to tell the socket which hook it came in on. */ | /* Try to tell the socket which hook it came in on. */ | ||
- if (sbappendaddr(&so->so_rcv, (struct sockaddr *)addr, m, NULL) == 0) { | + SOCKBUF_LOCK(&so->so_rcv); | ||
+ if (sbappendaddr_loc | |||
+ NULL) == 0) { | |||
+ SOCKBUF_UNLOCK(&so->so_rcv); | |||
m_freem(m); | m_freem(m); | ||
TRAP_ERROR; | TRAP_ERROR; | ||
return (ENOBUFS); | return (ENOBUFS); | ||
} | } | ||
- sorwakeup(so); | + | ||
+ /* sorwakeup_locked | |||
+ sorwakeup_locked | |||
return (0); | return (0); | ||
} | } | ||
@@ -140,7 +140,7 @@ void audit_arg_argv(c | |||
void audit_arg_envv(char *envv, int envc, int length); | void audit_arg_envv(char *envv, int envc, int length); | ||
void audit_arg_rights | void audit_arg_rights | ||
void audit_arg_fcntl_ | void audit_arg_fcntl_ | ||
-void audit_sysclose(struct thread *td, int fd); | +void audit_sysclose(struct thread *td, int fd, struct file *fp); | ||
void audit_cred_copy(struct ucred *src, struct ucred *dest); | void audit_cred_copy(struct ucred *src, struct ucred *dest); | ||
void audit_cred_destr | void audit_cred_destr | ||
void audit_cred_init(struct ucred *cred); | void audit_cred_init(struct ucred *cred); |
@@ -995,12 +995,10 @@ audit_arg_fcntl_ | |||
* call itself. | * call itself. | ||
*/ | */ | ||
void | void | ||
-audit_sysclose(struct thread *td, int fd) | +audit_sysclose(struct thread *td, int fd, struct file *fp) | ||
{ | { | ||
- cap_rights_t rights; | |||
struct kaudit_record *ar; | struct kaudit_record *ar; | ||
struct vnode *vp; | struct vnode *vp; | ||
- struct file *fp; | |||
KASSERT(td != NULL, ("audit_sysclose: td == NULL")); | KASSERT(td != NULL, ("audit_sysclose: td == NULL")); | ||
@@ -1010,12 +1008,10 @@ audit_sysclose(s | |||
audit_arg_fd(fd); | audit_arg_fd(fd); | ||
- if (getvnode(td, fd, cap_rights_init(&rights), &fp) != 0) | |||
- return; | |||
- | |||
vp = fp->f_vnode; | vp = fp->f_vnode; | ||
+ if (vp == NULL) | |||
+ return; | |||
vn_lock(vp, LK_SHARED | LK_RETRY); | vn_lock(vp, LK_SHARED | LK_RETRY); | ||
audit_arg_vnode1 | audit_arg_vnode1 | ||
VOP_UNLOCK(vp); | VOP_UNLOCK(vp); | ||
- fdrop(fp, td); | |||
} | } |
@@ -143,7 +143,7 @@ if (opt_l) { | |||
for (file_i = 0; file_i < num_files; file_i++) { | for (file_i = 0; file_i < num_files; file_i++) { | ||
symb = filenames[file_i]; | symb = filenames[file_i]; | ||
- # '-', '.' and '/' are converted to '_' | + # '-', '.' and '/' are converted to '_' | ||
gsub(/-|\.|\//, "_", symb); | gsub(/-|\.|\//, "_", symb); | ||
printc("extern char _binary_" symb "_start[], _binary_" symb "_end[];"); | printc("extern char _binary_" symb "_start[], _binary_" symb "_end[];"); | ||
} | } | ||
@@ -170,7 +170,7 @@ for (file_i = 0; file_i < num_files; file_i++) { | |||
short = shortnames[file_i]; | short = shortnames[file_i]; | ||
symb = filenames[file_i]; | symb = filenames[file_i]; | ||
version = versions[file_i]; | version = versions[file_i]; | ||
- # '-', '.' and '/' are converted to '_' | + # '-', '.' and '/' are converted to '_' | ||
gsub(/-|\.|\//, "_", symb); | gsub(/-|\.|\//, "_", symb); | ||
reg = "\t\tfp = "; | reg = "\t\tfp = "; |
@@ -47,9 +47,6 @@ epair_stress_hea | |||
} | } | ||
epair_stress_bod | epair_stress_bod | ||
{ | { | ||
- if [ "$(atf_config_get ci false)" = "true" ]; then | |||
- atf_skip "https://bugs.freebsd.org/246443" | |||
- fi | |||
do_stress "epair" | do_stress "epair" | ||
} | } | ||
epair_stress_cle | epair_stress_cle | ||
@@ -80,7 +77,6 @@ epair_ipv6_up_st | |||
} | } | ||
epair_ipv6_up_st | epair_ipv6_up_st | ||
{ | { | ||
- atf_skip "Quickly panics: page fault in in6_unlink_ifa (PR 225438)" | |||
do_up_stress "epair" "6" "" | do_up_stress "epair" "6" "" | ||
} | } | ||
epair_ipv6_up_st | epair_ipv6_up_st | ||
@@ -111,7 +107,6 @@ faith_up_stress_ | |||
} | } | ||
faith_up_stress_ | faith_up_stress_ | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "faith" "" "" | do_up_stress "faith" "" "" | ||
} | } | ||
faith_up_stress_ | faith_up_stress_ | ||
@@ -127,7 +122,6 @@ faith_ipv6_up_st | |||
} | } | ||
faith_ipv6_up_st | faith_ipv6_up_st | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "faith" "6" "" | do_up_stress "faith" "6" "" | ||
} | } | ||
faith_ipv6_up_st | faith_ipv6_up_st | ||
@@ -158,7 +152,6 @@ gif_up_stress_he | |||
} | } | ||
gif_up_stress_bo | gif_up_stress_bo | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "gif" "" "p2p" | do_up_stress "gif" "" "p2p" | ||
} | } | ||
gif_up_stress_cl | gif_up_stress_cl | ||
@@ -174,7 +167,6 @@ gif_ipv6_up_stre | |||
} | } | ||
gif_ipv6_up_stre | gif_ipv6_up_stre | ||
{ | { | ||
- atf_skip "Quickly panics: rt_tables_get_rn | |||
do_up_stress "gif" "6" "p2p" | do_up_stress "gif" "6" "p2p" | ||
} | } | ||
gif_ipv6_up_stre | gif_ipv6_up_stre | ||
@@ -205,7 +197,6 @@ lo_up_stress_hea | |||
} | } | ||
lo_up_stress_bod | lo_up_stress_bod | ||
{ | { | ||
- atf_skip "Quickly panics: GPF in rtsock_routemsg" | |||
do_up_stress "lo" "" "" | do_up_stress "lo" "" "" | ||
} | } | ||
lo_up_stress_cle | lo_up_stress_cle | ||
@@ -221,7 +212,6 @@ lo_ipv6_up_stres | |||
} | } | ||
lo_ipv6_up_stres | lo_ipv6_up_stres | ||
{ | { | ||
- atf_skip "Quickly panics: page fault in rtsock_addrmsg" | |||
do_up_stress "lo" "6" "" | do_up_stress "lo" "6" "" | ||
} | } | ||
lo_ipv6_up_stres | lo_ipv6_up_stres | ||
@@ -252,7 +242,6 @@ tap_up_stress_he | |||
} | } | ||
tap_up_stress_bo | tap_up_stress_bo | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "tap" "" "" | do_up_stress "tap" "" "" | ||
} | } | ||
tap_up_stress_cl | tap_up_stress_cl | ||
@@ -299,7 +288,6 @@ tun_up_stress_he | |||
} | } | ||
tun_up_stress_bo | tun_up_stress_bo | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "tun" "" "p2p" | do_up_stress "tun" "" "p2p" | ||
} | } | ||
tun_up_stress_cl | tun_up_stress_cl | ||
@@ -315,7 +303,6 @@ tun_ipv6_up_stre | |||
} | } | ||
tun_ipv6_up_stre | tun_ipv6_up_stre | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "tun" "6" "p2p" | do_up_stress "tun" "6" "p2p" | ||
} | } | ||
tun_ipv6_up_stre | tun_ipv6_up_stre | ||
@@ -346,7 +333,6 @@ vlan_up_stress_h | |||
} | } | ||
vlan_up_stress_b | vlan_up_stress_b | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "vlan" "" "" | do_up_stress "vlan" "" "" | ||
} | } | ||
vlan_up_stress_c | vlan_up_stress_c | ||
@@ -362,7 +348,6 @@ vlan_ipv6_up_str | |||
} | } | ||
vlan_ipv6_up_str | vlan_ipv6_up_str | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "vlan" "6" "" | do_up_stress "vlan" "6" "" | ||
} | } | ||
vlan_ipv6_up_str | vlan_ipv6_up_str | ||
@@ -408,7 +393,6 @@ vmnet_ipv6_up_st | |||
} | } | ||
vmnet_ipv6_up_st | vmnet_ipv6_up_st | ||
{ | { | ||
- atf_skip "Quickly panics: if_freemulti: protospec not NULL" | |||
do_up_stress "vmnet" "6" "" | do_up_stress "vmnet" "6" "" | ||
} | } | ||
vmnet_ipv6_up_st | vmnet_ipv6_up_st |
@@ -17,4 +17,5 @@ LUACHECK=$(which | |||
cd $(make -V SRCTOP)/stand | cd $(make -V SRCTOP)/stand | ||
${LUACHECK} . --globals loader --globals lfs --globals io.getchar \ | ${LUACHECK} . --globals loader --globals lfs --globals io.getchar \ | ||
--globals io.ischar --globals printc --globals cli_execute \ | --globals io.ischar --globals printc --globals cli_execute \ | ||
- --globals cli_execute_unparsed --globals try_include | + --globals cli_execute_unparsed --globals try_include \ | ||
+ --globals pager --std lua53 |
@@ -0,0 +1,64 @@ | |||
+#!/bin/sh | |||
+ | |||
+case "$2" in | |||
+commit|message) | |||
+ # It appears git invokes this script for interactive rebase but does | |||
+ # not remove commented lines, so just exit if we're not called with the | |||
+ # default (comment-containing) template. | |||
+ egrep -q '^#' "$1" || return 0 | |||
+ ;; | |||
+template) | |||
+ return 0 | |||
+ ;; | |||
+merge) | |||
+ return 0 | |||
+ ;; | |||
+esac | |||
+ | |||
+outfile=$(mktemp /tmp/freebsd-git-commit.XXXXXXXX) | |||
+ | |||
+# Create a commit message template from three parts: | |||
+# | |||
+# 1. The beginning of the git-provided template (up to the first comment-only | |||
+# line) which explains commented lines and such. | |||
+# 2. Our template. | |||
+# 3. The remainder of the git-provided template (from the first comment-only | |||
+# line to the end of the file) which lists files staged for commit, files | |||
+# not staged, and untracked files. | |||
+ | |||
+cat >$outfile <<EOF | |||
+$(awk '1;/^#$/{exit}' $1) | |||
+# Uncomment and complete these metadata fields, as appropriate: | |||
+# | |||
+# PR: | |||
+# Submitted by: | |||
+# Reported by: | |||
+# Reviewed by: | |||
+# Approved by: | |||
+# Obtained from: | |||
+# MFC after: | |||
+# MFH: | |||
+# Relnotes: | |||
+# Security: | |||
+# Sponsored by: | |||
+# Pull Request: | |||
+# Differential Revision: | |||
+# | |||
+# Description of fields to fill in above: 72 columns --| | |||
+# PR: If and which Problem Report is related. | |||
+# Submitted by: If someone else sent in the change. | |||
+# Reported by: If someone else reported the issue. | |||
+# Reviewed by: If someone else reviewed your modification. | |||
+# Approved by: If you needed approval for this commit. | |||
+# Obtained from: If the change is from a third party. | |||
+# MFC after: N [day[s]|week[s]|month[s]]. Request a reminder email. | |||
+# MFH: Ports tree branch name. Request approval for merge. | |||
+# Relnotes: Set to 'yes' for mention in release notes. | |||
+# Security: Vulnerability reference (one per line) or description. | |||
+# Sponsored by: If the change was sponsored by an organization. | |||
+# Pull Request: https://github.com/freebsd/<repo>/pull/### (*full* GitHub URL needed). | |||
+# Differential Revision: https://reviews.freebsd.org/D### (*full* phabric URL needed). | |||
+$(awk '/^#$/,EOF' $1) | |||
+EOF | |||
+ | |||
+mv $outfile $1 |
@@ -1,5 +1,7 @@ | |||
# $FreeBSD$ | # $FreeBSD$ | ||
+.include <src.opts.mk> | |||
+ | |||
.include "${SRCTOP}/lib/kyua/Makefile.kyua" | .include "${SRCTOP}/lib/kyua/Makefile.kyua" | ||
.PATH: ${KYUA_SRCDIR} | .PATH: ${KYUA_SRCDIR} | ||
@@ -28,7 +30,11 @@ CFLAGS+= -I${KYUA_SRCDIR} | |||
# kyua uses auto_ptr | # kyua uses auto_ptr | ||
CFLAGS+= -Wno-deprecated-declarations | CFLAGS+= -Wno-deprecated-declarations | ||
-FILESGROUPS= DOCS | +FILESGROUPS= DOCS MISC STORE | ||
+ | |||
+.if ${MK_EXAMPLES} != "no" | |||
+FILESGROUPS+= EXAMPLES | |||
+.endif | |||
# Install a minimal default config that uses the 'tests' user. | # Install a minimal default config that uses the 'tests' user. | ||
# The examples config is not appropriate for general use. | # The examples config is not appropriate for general use. |
@@ -111,6 +111,8 @@ struct pci_vtnet_softc { | |||
net_backend_t *vsc_be; | net_backend_t *vsc_be; | ||
+ bool features_negotia | |||
+ | |||
int resetting; /* protected by tx_mtx */ | int resetting; /* protected by tx_mtx */ | ||
uint64_t vsc_features; /* negotiated features */ | uint64_t vsc_features; /* negotiated features */ | ||
@@ -176,6 +178,7 @@ pci_vtnet_reset( | |||
* Receive operation will be enabled again once the guest adds | * Receive operation will be enabled again once the guest adds | ||
* the first receive buffers and kicks us. | * the first receive buffers and kicks us. | ||
*/ | */ | ||
+ sc->features_negotia | |||
netbe_rx_disable | netbe_rx_disable | ||
/* Set sc->resetting and give a chance to the TX thread to stop. */ | /* Set sc->resetting and give a chance to the TX thread to stop. */ | ||
@@ -246,6 +249,12 @@ pci_vtnet_rx(str | |||
struct vqueue_info *vq; | struct vqueue_info *vq; | ||
vq = &sc->vsc_queues[VTNET_RXQ]; | vq = &sc->vsc_queues[VTNET_RXQ]; | ||
+ | |||
+ /* Features must be negotiated */ | |||
+ if (!sc->features_negotia | |||
+ return; | |||
+ } | |||
+ | |||
for (;;) { | for (;;) { | ||
struct virtio_net_rxhdr | struct virtio_net_rxhdr | ||
uint32_t riov_bytes; | uint32_t riov_bytes; | ||
@@ -406,8 +415,14 @@ pci_vtnet_ping_r | |||
/* | /* | ||
* A qnotify means that the rx process can now begin. | * A qnotify means that the rx process can now begin. | ||
+ * Enable RX only if features are negotiated. | |||
*/ | */ | ||
pthread_mutex_lo | pthread_mutex_lo | ||
+ if (!sc->features_negotia | |||
+ pthread_mutex_un | |||
+ return; | |||
+ } | |||
+ | |||
vq_kick_disable(vq); | vq_kick_disable(vq); | ||
netbe_rx_enable(sc->vsc_be); | netbe_rx_enable(sc->vsc_be); | ||
pthread_mutex_un | pthread_mutex_un | ||
@@ -750,6 +765,10 @@ pci_vtnet_neg_fe | |||
netbe_set_cap(sc->vsc_be, negotiated_featu | netbe_set_cap(sc->vsc_be, negotiated_featu | ||
sc->be_vhdrlen = netbe_get_vnet_h | sc->be_vhdrlen = netbe_get_vnet_h | ||
assert(sc->be_vhdrlen == 0 || sc->be_vhdrlen == sc->vhdrlen); | assert(sc->be_vhdrlen == 0 || sc->be_vhdrlen == sc->vhdrlen); | ||
+ | |||
+ pthread_mutex_lo | |||
+ sc->features_negotia | |||
+ pthread_mutex_un | |||
} | } | ||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT |
@@ -731,7 +731,7 @@ | |||
#define PACKAGE_NAME "unbound" | #define PACKAGE_NAME "unbound" | ||
/* Define to the full name and version of this package. */ | /* Define to the full name and version of this package. */ | ||
-#define PACKAGE_STRING "unbound 1. | +#define PACKAGE_STRING "unbound 1.13.0" | ||
/* Define to the one symbol short name of this package. */ | /* Define to the one symbol short name of this package. */ | ||
#define PACKAGE_TARNAME "unbound" | #define PACKAGE_TARNAME "unbound" | ||
@@ -740,7 +740,7 @@ | |||
#define PACKAGE_URL "" | #define PACKAGE_URL "" | ||
/* Define to the version of this package. */ | /* Define to the version of this package. */ | ||
-#define PACKAGE_VERSION "1. | +#define PACKAGE_VERSION "1.13.0" | ||
/* default pidfile location */ | /* default pidfile location */ | ||
#define PIDFILE "/var/unbound/unbound.pid" | #define PIDFILE "/var/unbound/unbound.pid" | ||
@@ -762,7 +762,7 @@ | |||
#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem" | #define ROOT_CERT_FILE "/var/unbound/icannbundle.pem" | ||
/* version number for resource files */ | /* version number for resource files */ | ||
-#define RSRC_PACKAGE_VERSION 1, | +#define RSRC_PACKAGE_VERSION 1,13,0,0 | ||
/* Directory to chdir to */ | /* Directory to chdir to */ | ||
#define RUN_DIR "/var/unbound" | #define RUN_DIR "/var/unbound" |