svn commit: r349227 - stable/11/sys/dev/drm2/i915
Andriy Gapon
avg at FreeBSD.org
Thu Jun 20 09:23:04 UTC 2019
Author: avg
Date: Thu Jun 20 09:23:03 2019
New Revision: 349227
URL: https://svnweb.freebsd.org/changeset/base/349227
Log:
drm2/intel_iic: stop using iicbus_set_nostop
The desired mode of transmitting messages is implemented by subclassing
iicbb driver and overriding its iicbus_transfer method with an almost
identical copy that issues the stop condition only at the very end.
iicbus_set_nostop is very broken and is set to be removed from the KPI.
This is a direct commit as in head the drm drivers have been moved out
of the tree.
The same change has been committed to FreeBSDDesktop/drm-legacy.
Modified:
stable/11/sys/dev/drm2/i915/intel_iic.c
Modified: stable/11/sys/dev/drm2/i915/intel_iic.c
==============================================================================
--- stable/11/sys/dev/drm2/i915/intel_iic.c Thu Jun 20 07:50:38 2019 (r349226)
+++ stable/11/sys/dev/drm2/i915/intel_iic.c Thu Jun 20 09:23:03 2019 (r349227)
@@ -562,12 +562,11 @@ intel_iicbb_attach(device_t idev)
sc->bus = &dev_priv->gmbus[pin];
/* add generic bit-banging code */
- sc->iic_dev = device_add_child(idev, "iicbb", -1);
+ sc->iic_dev = device_add_child(idev, "iicbb_nostop", -1);
if (sc->iic_dev == NULL)
return (ENXIO);
device_quiet(sc->iic_dev);
bus_generic_attach(idev);
- iicbus_set_nostop(idev, true);
return (0);
}
@@ -608,8 +607,84 @@ static driver_t intel_iicbb_driver = {
static devclass_t intel_iicbb_devclass;
DRIVER_MODULE_ORDERED(intel_iicbb, drmn, intel_iicbb_driver,
intel_iicbb_devclass, 0, 0, SI_ORDER_FIRST);
-DRIVER_MODULE(iicbb, intel_iicbb, iicbb_driver, iicbb_devclass, 0, 0);
+/*
+ * XXX This is a copy of struct iicbb_softc in sys/dev/iicbus/iicbb.c.
+ * There should really be a shared definition.
+ */
+struct iicbb_softc {
+ device_t iicbus;
+ int udelay; /* signal toggle delay in usec */
+};
+
+static int
+iicbb_nostop_transfer_impl(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+ int i, error, lenread, lenwrote, addr;
+ struct iicbb_softc *sc;
+ device_t bus;
+ bool started;
+
+ sc = device_get_softc(dev);
+ bus = sc->iicbus;
+ started = false;
+ for (i = 0, error = 0; i < nmsgs && error == 0; i++) {
+ addr = msgs[i].slave;
+ if (msgs[i].flags & IIC_M_RD)
+ addr |= LSB;
+ else
+ addr &= ~LSB;
+
+ if ((msgs[i].flags & IIC_M_NOSTART) == 0) {
+ if (i == 0)
+ error = iicbus_start(bus, addr, 0);
+ else
+ error = iicbus_repeated_start(bus, addr, 0);
+ if (error != 0)
+ break;
+ started = true;
+ }
+
+ if ((msgs[i].flags & IIC_M_RD) != 0)
+ error = iicbus_read(bus, msgs[i].buf, msgs[i].len,
+ &lenread, IIC_LAST_READ, 0);
+ else
+ error = iicbus_write(bus, msgs[i].buf, msgs[i].len,
+ &lenwrote, 0);
+ }
+ if (started)
+ iicbus_stop(bus);
+ return (error);
+}
+
+static int
+iicbb_nostop_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+ int error;
+
+ error = IICBB_PRE_XFER(device_get_parent(dev));
+ if (error)
+ return (error);
+
+ error = iicbb_nostop_transfer_impl(dev, msgs, nmsgs);
+
+ IICBB_POST_XFER(device_get_parent(dev));
+ return (error);
+}
+
+static device_method_t iicbb_nostop_methods[] = {
+ DEVMETHOD(iicbus_transfer, iicbb_nostop_transfer),
+
+ DEVMETHOD_END
+};
+
+static devclass_t iicbb_nostop_devclass;
+
+DEFINE_CLASS_1(iicbb_nostop, iicbb_nostop_driver, iicbb_nostop_methods,
+ sizeof(struct iicbb_softc), iicbb_driver);
+DRIVER_MODULE(iicbb_nostop, intel_iicbb, iicbb_nostop_driver,
+ iicbb_nostop_devclass, NULL, NULL);
+
/**
* intel_gmbus_setup - instantiate all Intel i2c GMBuses
* @dev: DRM device
@@ -672,7 +747,7 @@ int intel_setup_gmbus(struct drm_device *dev)
/* bbbus */
iic_dev = device_find_child(bus->bbbus_bridge,
- "iicbb", -1);
+ "iicbb_nostop", -1);
if (iic_dev == NULL) {
DRM_ERROR("bbbus bridge doesn't have iicbb child\n");
goto err;
More information about the svn-src-stable-11
mailing list