summaryrefslogtreecommitdiffstats
path: root/drivers/soundwire/intel.c
diff options
context:
space:
mode:
authorLinus Torvalds2018-10-26 18:11:43 +0200
committerLinus Torvalds2018-10-26 18:11:43 +0200
commit18d0eae30e6a4f8644d589243d7ac1d70d29203d (patch)
treefef5a78d54b8763cb17867018356cfe311b31036 /drivers/soundwire/intel.c
parentMerge tag 'driver-core-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel... (diff)
parentDocumentation/security-bugs: Clarify treatment of embargoed information (diff)
downloadkernel-qcow2-linux-18d0eae30e6a4f8644d589243d7ac1d70d29203d.tar.gz
kernel-qcow2-linux-18d0eae30e6a4f8644d589243d7ac1d70d29203d.tar.xz
kernel-qcow2-linux-18d0eae30e6a4f8644d589243d7ac1d70d29203d.zip
Merge tag 'char-misc-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the big set of char/misc patches for 4.20-rc1. Loads of things here, we have new code in all of these driver subsystems: - fpga - stm - extcon - nvmem - eeprom - hyper-v - gsmi - coresight - thunderbolt - vmw_balloon - goldfish - soundwire along with lots of fixes and minor changes to other small drivers. All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (245 commits) Documentation/security-bugs: Clarify treatment of embargoed information lib: Fix ia64 bootloader linkage MAINTAINERS: Clarify UIO vs UIOVEC maintainer docs/uio: fix a grammar nitpick docs: fpga: document programming fpgas using regions fpga: add devm_fpga_region_create fpga: bridge: add devm_fpga_bridge_create fpga: mgr: add devm_fpga_mgr_create hv_balloon: Replace spin_is_locked() with lockdep sgi-xp: Replace spin_is_locked() with lockdep eeprom: New ee1004 driver for DDR4 memory eeprom: at25: remove unneeded 'at25_remove' w1: IAD Register is yet readable trough iad sys file. Fix snprintf (%u for unsigned, count for max size). misc: mic: scif: remove set but not used variables 'src_dma_addr, dst_dma_addr' misc: mic: fix a DMA pool free failure platform: goldfish: pipe: Add a blank line to separate varibles and code platform: goldfish: pipe: Remove redundant casting platform: goldfish: pipe: Call misc_deregister if init fails platform: goldfish: pipe: Move the file-scope goldfish_pipe_dev variable into the driver state platform: goldfish: pipe: Move the file-scope goldfish_pipe_miscdev variable into the driver state ...
Diffstat (limited to 'drivers/soundwire/intel.c')
-rw-r--r--drivers/soundwire/intel.c68
1 files changed, 65 insertions, 3 deletions
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 0a8990e758f9..c5ee97ee7886 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -398,6 +398,69 @@ static int intel_config_stream(struct sdw_intel *sdw,
}
/*
+ * bank switch routines
+ */
+
+static int intel_pre_bank_switch(struct sdw_bus *bus)
+{
+ struct sdw_cdns *cdns = bus_to_cdns(bus);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ void __iomem *shim = sdw->res->shim;
+ int sync_reg;
+
+ /* Write to register only for multi-link */
+ if (!bus->multi_link)
+ return 0;
+
+ /* Read SYNC register */
+ sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
+ sync_reg |= SDW_SHIM_SYNC_CMDSYNC << sdw->instance;
+ intel_writel(shim, SDW_SHIM_SYNC, sync_reg);
+
+ return 0;
+}
+
+static int intel_post_bank_switch(struct sdw_bus *bus)
+{
+ struct sdw_cdns *cdns = bus_to_cdns(bus);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
+ void __iomem *shim = sdw->res->shim;
+ int sync_reg, ret;
+
+ /* Write to register only for multi-link */
+ if (!bus->multi_link)
+ return 0;
+
+ /* Read SYNC register */
+ sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
+
+ /*
+ * post_bank_switch() ops is called from the bus in loop for
+ * all the Masters in the steam with the expectation that
+ * we trigger the bankswitch for the only first Master in the list
+ * and do nothing for the other Masters
+ *
+ * So, set the SYNCGO bit only if CMDSYNC bit is set for any Master.
+ */
+ if (!(sync_reg & SDW_SHIM_SYNC_CMDSYNC_MASK))
+ return 0;
+
+ /*
+ * Set SyncGO bit to synchronously trigger a bank switch for
+ * all the masters. A write to SYNCGO bit clears CMDSYNC bit for all
+ * the Masters.
+ */
+ sync_reg |= SDW_SHIM_SYNC_SYNCGO;
+
+ ret = intel_clear_bit(shim, SDW_SHIM_SYNC, sync_reg,
+ SDW_SHIM_SYNC_SYNCGO);
+ if (ret < 0)
+ dev_err(sdw->cdns.dev, "Post bank switch failed: %d", ret);
+
+ return ret;
+}
+
+/*
* DAI routines
*/
@@ -750,6 +813,8 @@ static struct sdw_master_ops sdw_intel_ops = {
.xfer_msg_defer = cdns_xfer_msg_defer,
.reset_page_addr = cdns_reset_page_addr,
.set_bus_conf = cdns_bus_conf,
+ .pre_bank_switch = intel_pre_bank_switch,
+ .post_bank_switch = intel_post_bank_switch,
};
/*
@@ -780,9 +845,6 @@ static int intel_probe(struct platform_device *pdev)
sdw_intel_ops.read_prop = intel_prop_read;
sdw->cdns.bus.ops = &sdw_intel_ops;
- sdw_intel_ops.read_prop = intel_prop_read;
- sdw->cdns.bus.ops = &sdw_intel_ops;
-
platform_set_drvdata(pdev, sdw);
ret = sdw_add_bus_master(&sdw->cdns.bus);