static int ssi_clk_event()

in controllers/omap_ssi_core.c [268:324]


static int ssi_clk_event(struct notifier_block *nb, unsigned long event,
								void *data)
{
	struct omap_ssi_controller *omap_ssi = container_of(nb,
					struct omap_ssi_controller, fck_nb);
	struct hsi_controller *ssi = to_hsi_controller(omap_ssi->dev);
	struct clk_notifier_data *clk_data = data;
	struct omap_ssi_port *omap_port;
	int i;

	switch (event) {
	case PRE_RATE_CHANGE:
		dev_dbg(&ssi->device, "pre rate change\n");

		for (i = 0; i < ssi->num_ports; i++) {
			omap_port = omap_ssi->port[i];

			if (!omap_port)
				continue;

			/* Workaround for SWBREAK + CAwake down race in CMT */
			disable_irq(omap_port->wake_irq);

			/* stop all ssi communication */
			pinctrl_pm_select_idle_state(omap_port->pdev);
			udelay(1); /* wait for racing frames */
		}

		break;
	case ABORT_RATE_CHANGE:
		dev_dbg(&ssi->device, "abort rate change\n");
		fallthrough;
	case POST_RATE_CHANGE:
		dev_dbg(&ssi->device, "post rate change (%lu -> %lu)\n",
			clk_data->old_rate, clk_data->new_rate);
		omap_ssi->fck_rate = DIV_ROUND_CLOSEST(clk_data->new_rate, 1000); /* kHz */

		for (i = 0; i < ssi->num_ports; i++) {
			omap_port = omap_ssi->port[i];

			if (!omap_port)
				continue;

			omap_ssi_port_update_fclk(ssi, omap_port);

			/* resume ssi communication */
			pinctrl_pm_select_default_state(omap_port->pdev);
			enable_irq(omap_port->wake_irq);
		}

		break;
	default:
		break;
	}

	return NOTIFY_DONE;
}