Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2083057a authored by Sebastian Reichel's avatar Sebastian Reichel
Browse files

HSI: omap_ssi_port: replace wkin_cken with atomic bitmap operations



This simplifies the code and avoids holding a spin_lock when
runtime pm calls are made. Once the irq_safe flag is removed
for omap_ssi's runtime pm, pm_runtime_get/put_sync can sleep,
which is a no-go while holding a spin_lock.

Signed-off-by: default avatarSebastian Reichel <sre@kernel.org>
Tested-by: default avatarPavel Machek <pavel@ucw.cz>
parent cb70e4c1
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -35,6 +35,8 @@
#define SSI_MAX_GDD_LCH		8
#define SSI_MAX_GDD_LCH		8
#define SSI_BYTES_TO_FRAMES(x) ((((x) - 1) >> 2) + 1)
#define SSI_BYTES_TO_FRAMES(x) ((((x) - 1) >> 2) + 1)


#define SSI_WAKE_EN 0

/**
/**
 * struct omap_ssm_ctx - OMAP synchronous serial module (TX/RX) context
 * struct omap_ssm_ctx - OMAP synchronous serial module (TX/RX) context
 * @mode: Bit transmission mode
 * @mode: Bit transmission mode
@@ -75,7 +77,7 @@ struct omap_ssm_ctx {
 * @wake_irq: IRQ number for incoming wake line (-1 if none)
 * @wake_irq: IRQ number for incoming wake line (-1 if none)
 * @wake_gpio: GPIO number for incoming wake line (-1 if none)
 * @wake_gpio: GPIO number for incoming wake line (-1 if none)
 * @pio_tasklet: Bottom half for PIO transfers and events
 * @pio_tasklet: Bottom half for PIO transfers and events
 * @wkin_cken: Keep track of clock references due to the incoming wake line
 * @flags: flags to keep track of states
 * @wk_refcount: Reference count for output wake line
 * @wk_refcount: Reference count for output wake line
 * @sys_mpu_enable: Context for the interrupt enable register for irq 0
 * @sys_mpu_enable: Context for the interrupt enable register for irq 0
 * @sst: Context for the synchronous serial transmitter
 * @sst: Context for the synchronous serial transmitter
@@ -99,7 +101,7 @@ struct omap_ssi_port {
	struct gpio_desc	*wake_gpio;
	struct gpio_desc	*wake_gpio;
	struct tasklet_struct	pio_tasklet;
	struct tasklet_struct	pio_tasklet;
	bool			wktest:1; /* FIXME: HACK to be removed */
	bool			wktest:1; /* FIXME: HACK to be removed */
	bool			wkin_cken:1; /* Workaround */
	unsigned long		flags;
	unsigned int		wk_refcount;
	unsigned int		wk_refcount;
	/* OMAP SSI port context */
	/* OMAP SSI port context */
	u32			sys_mpu_enable; /* We use only one irq */
	u32			sys_mpu_enable; /* We use only one irq */
+3 −13
Original line number Original line Diff line number Diff line
@@ -751,10 +751,8 @@ static int ssi_release(struct hsi_client *cl)
		 * Drop the clock reference for the incoming wake line
		 * Drop the clock reference for the incoming wake line
		 * if it is still kept high by the other side.
		 * if it is still kept high by the other side.
		 */
		 */
		if (omap_port->wkin_cken) {
		if (test_and_clear_bit(SSI_WAKE_EN, &omap_port->flags))
			pm_runtime_put_sync(omap_port->pdev);
			pm_runtime_put_sync(omap_port->pdev);
			omap_port->wkin_cken = 0;
		}
		pm_runtime_get_sync(omap_port->pdev);
		pm_runtime_get_sync(omap_port->pdev);
		/* Stop any SSI TX/RX without a client */
		/* Stop any SSI TX/RX without a client */
		ssi_set_port_mode(omap_port, SSI_MODE_SLEEP);
		ssi_set_port_mode(omap_port, SSI_MODE_SLEEP);
@@ -981,12 +979,8 @@ static irqreturn_t ssi_wake_thread(int irq __maybe_unused, void *ssi_port)
		 * This workaround will avoid breaking the clock reference
		 * This workaround will avoid breaking the clock reference
		 * count when such a situation ocurrs.
		 * count when such a situation ocurrs.
		 */
		 */
		spin_lock(&omap_port->lock);
		if (!test_and_set_bit(SSI_WAKE_EN, &omap_port->flags))
		if (!omap_port->wkin_cken) {
			omap_port->wkin_cken = 1;
			pm_runtime_get_sync(omap_port->pdev);
			pm_runtime_get_sync(omap_port->pdev);
		}
		spin_unlock(&omap_port->lock);
		dev_dbg(&ssi->device, "Wake in high\n");
		dev_dbg(&ssi->device, "Wake in high\n");
		if (omap_port->wktest) { /* FIXME: HACK ! To be removed */
		if (omap_port->wktest) { /* FIXME: HACK ! To be removed */
			writel(SSI_WAKE(0),
			writel(SSI_WAKE(0),
@@ -1000,12 +994,8 @@ static irqreturn_t ssi_wake_thread(int irq __maybe_unused, void *ssi_port)
				omap_ssi->sys + SSI_CLEAR_WAKE_REG(port->num));
				omap_ssi->sys + SSI_CLEAR_WAKE_REG(port->num));
		}
		}
		hsi_event(port, HSI_EVENT_STOP_RX);
		hsi_event(port, HSI_EVENT_STOP_RX);
		spin_lock(&omap_port->lock);
		if (test_and_clear_bit(SSI_WAKE_EN, &omap_port->flags))
		if (omap_port->wkin_cken) {
			pm_runtime_put_sync(omap_port->pdev);
			pm_runtime_put_sync(omap_port->pdev);
			omap_port->wkin_cken = 0;
		}
		spin_unlock(&omap_port->lock);
	}
	}


	return IRQ_HANDLED;
	return IRQ_HANDLED;