+
+ ret = madera_check_speaker_overheat(madera, &warn, &shutdown);
+ if (ret)
+ shutdown = true; /* for safety attempt to shutdown on error */
+
+ if (shutdown) {
+ dev_crit(madera->dev, "Thermal shutdown\n");
+ ret = regmap_update_bits(madera->regmap,
+ MADERA_OUTPUT_ENABLES_1,
+ MADERA_OUT4L_ENA |
+ MADERA_OUT4R_ENA, 0);
+ if (ret != 0)
+ dev_crit(madera->dev,
+ "Failed to disable speaker outputs: %d\n",
+ ret);
+ } else if (warn) {
+ dev_crit(madera->dev, "Thermal warning\n");
+ }
+
+ return IRQ_HANDLED;
We will flag the interrupt as handled if there was neither a warning nor
a critical overheat? I'd expect some warning about a spurious interrupt
at least.
+static int madera_get_variable_u32_array(struct madera_priv *priv,
+ const char *propname,
+ u32 *dest,
+ int n_max,
+ int multiple)
+{
+ struct madera *madera = priv->madera;
+ int n, ret;
+
+ n = device_property_read_u32_array(madera->dev, propname, NULL, 0);
+ if (n == -EINVAL) {
+ return 0; /* missing, ignore */
+ } else if (n < 0) {
+ dev_warn(madera->dev, "%s malformed (%d)\n",
+ propname, n);
+ return n;
+ } else if ((n % multiple) != 0) {
+ dev_warn(madera->dev, "%s not a multiple of %d entries\n",
+ propname, multiple);
+ return -EINVAL;
+ }
+
+ if (n > n_max)
+ n = n_max;
+
+ ret = device_property_read_u32_array(madera->dev, propname, dest, n);
+
+ if (ret < 0)
+ return ret;
+ else
+ return n;
+}
This feels like it should perhaps be a generic OF helper function -
there's nothing driver specific I'm seeing here and arrays that need to
be a multiple of N entries aren't that uncommon I think.
+ mutex_lock(&priv->rate_lock);
+ cached_rate = priv->adsp_rate_cache[adsp_num];
+ mutex_unlock(&priv->rate_lock);
What's this lock protecting? The value can we read can change as soon
as the lock is released and we're just reading a single word here rather
than traversing a data structure that might change under us or
something.
+void madera_destroy_bus_error_irq(struct madera_priv *priv, int dsp_num)
+{
+ struct madera *madera = priv->madera;
+
+ madera_free_irq(madera,
+ madera_dsp_bus_error_irqs[dsp_num],
+ &priv->adsp[dsp_num]);
+}
+EXPORT_SYMBOL_GPL(madera_destroy_bus_error_irq);
We use free rather than destroy normally?
+static const char * const madera_dfc_width_text[MADERA_DFC_WIDTH_ENUM_SIZE] = {
+ "8bit", "16bit", "20bit", "24bit", "32bit",
+};
Spaces might make these more readable.
+static void madera_sleep(unsigned int delay)
+{
+ if (delay < 20) {
+ delay *= 1000;
+ usleep_range(delay, delay + 500);
+ } else {
+ msleep(delay);
+ }
+}
This feels like it might make sense as a helper function as well - I
could've sworn there was one already but I can't immediately find it.