]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'clk/clk-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 04:21:42 +0000 (15:21 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 04:21:42 +0000 (15:21 +1100)
1  2 
arch/arm/mach-at91/Kconfig
arch/arm/mach-bcm/Kconfig
drivers/base/power/domain.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/berlin/bg2q.c
drivers/clk/rockchip/clk-mmc-phase.c
drivers/clk/shmobile/clk-mstp.c
drivers/tty/serial/8250/8250_dw.c

index 9e4067cfecbed3e37751e6c08b9dcbf6a6d9415f,92673006e55c410ad27f60675c8e74bbf1433861..ec7a0641fefb0c57d0ab2f417f1b87c5ef60a1ca
@@@ -5,7 -5,6 +5,7 @@@ menuconfig ARCH_AT9
        select COMMON_CLK_AT91
        select PINCTRL
        select PINCTRL_AT91
 +      select PINCTRL_AT91PIO4
        select SOC_BUS
  
  if ARCH_AT91
@@@ -103,6 -102,9 +103,9 @@@ config HAVE_AT91_SM
  config HAVE_AT91_H32MX
        bool
  
+ config HAVE_AT91_GENERATED_CLK
+       bool
  config SOC_SAM_V4_V5
        bool
  
index 0be09af9dec724aec2ed818959753cebf84f85fe,84bd26535ae9d247a5f4c89eb6c95cfbaa643f6b..8c53c55be1feb318e84e2c2aba475b42646527c2
@@@ -14,7 -14,7 +14,7 @@@ config ARCH_BCM_IPRO
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select ARM_GLOBAL_TIMER
+       select COMMON_CLK_IPROC
        select CLKSRC_MMIO
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
@@@ -35,20 -35,6 +35,20 @@@ config ARCH_BCM_CYGNU
          BCM11300, BCM11320, BCM11350, BCM11360,
          BCM58300, BCM58302, BCM58303, BCM58305.
  
 +config ARCH_BCM_NSP
 +      bool "Broadcom Northstar Plus SoC Support" if ARCH_MULTI_V7
 +      select ARCH_BCM_IPROC
 +      select ARM_ERRATA_754322
 +      select ARM_ERRATA_775420
 +      help
 +        Support for Broadcom Northstar Plus SoC.
 +        Broadcom Northstar Plus family of SoCs are used for switching control
 +        and management applications as well as residential router/gateway
 +        applications. The SoC features dual core Cortex A9 ARM CPUs,
 +        integrating several peripheral interfaces including multiple Gigabit
 +        Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0 and USB 3.0, serial and
 +        NAND flash, SATA and several other IO controllers.
 +
  config ARCH_BCM_5301X
        bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
        select ARCH_BCM_IPROC
@@@ -161,7 -147,6 +161,7 @@@ config ARCH_BRCMST
        select BCM7120_L2_IRQ
        select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
        select ARCH_WANT_OPTIONAL_GPIOLIB
 +      select SOC_BRCMSTB
        help
          Say Y if you intend to run the kernel on a Broadcom ARM-based STB
          chipset.
index a7dfdf9f15bada9112d38c6c5616abbd40f3762c,222ce890124e629a1d783a44adcb33a962cf667c..80e29887038830a7bac36fe79d8c53912b828d81
        __ret;                                                  \
  })
  
 -#define GENPD_DEV_TIMED_CALLBACK(genpd, type, callback, dev, field, name)     \
 -({                                                                            \
 -      ktime_t __start = ktime_get();                                          \
 -      type __retval = GENPD_DEV_CALLBACK(genpd, type, callback, dev);         \
 -      s64 __elapsed = ktime_to_ns(ktime_sub(ktime_get(), __start));           \
 -      struct gpd_timing_data *__td = &dev_gpd_data(dev)->td;                  \
 -      if (!__retval && __elapsed > __td->field) {                             \
 -              __td->field = __elapsed;                                        \
 -              dev_dbg(dev, name " latency exceeded, new value %lld ns\n",     \
 -                      __elapsed);                                             \
 -              genpd->max_off_time_changed = true;                             \
 -              __td->constraint_changed = true;                                \
 -      }                                                                       \
 -      __retval;                                                               \
 -})
 -
  static LIST_HEAD(gpd_list);
  static DEFINE_MUTEX(gpd_list_lock);
  
 -static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
 -{
 -      struct generic_pm_domain *genpd = NULL, *gpd;
 -
 -      if (IS_ERR_OR_NULL(domain_name))
 -              return NULL;
 -
 -      mutex_lock(&gpd_list_lock);
 -      list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
 -              if (!strcmp(gpd->name, domain_name)) {
 -                      genpd = gpd;
 -                      break;
 -              }
 -      }
 -      mutex_unlock(&gpd_list_lock);
 -      return genpd;
 -}
 -
  /*
   * Get the generic PM domain for a particular struct device.
   * This validates the struct device pointer, the PM domain pointer,
@@@ -76,12 -110,18 +76,12 @@@ static struct generic_pm_domain *dev_to
  
  static int genpd_stop_dev(struct generic_pm_domain *genpd, struct device *dev)
  {
 -      return GENPD_DEV_TIMED_CALLBACK(genpd, int, stop, dev,
 -                                      stop_latency_ns, "stop");
 +      return GENPD_DEV_CALLBACK(genpd, int, stop, dev);
  }
  
 -static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev,
 -                      bool timed)
 +static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
  {
 -      if (!timed)
 -              return GENPD_DEV_CALLBACK(genpd, int, start, dev);
 -
 -      return GENPD_DEV_TIMED_CALLBACK(genpd, int, start, dev,
 -                                      start_latency_ns, "start");
 +      return GENPD_DEV_CALLBACK(genpd, int, start, dev);
  }
  
  static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
@@@ -100,6 -140,19 +100,6 @@@ static void genpd_sd_counter_inc(struc
        smp_mb__after_atomic();
  }
  
 -static void genpd_recalc_cpu_exit_latency(struct generic_pm_domain *genpd)
 -{
 -      s64 usecs64;
 -
 -      if (!genpd->cpuidle_data)
 -              return;
 -
 -      usecs64 = genpd->power_on_latency_ns;
 -      do_div(usecs64, NSEC_PER_USEC);
 -      usecs64 += genpd->cpuidle_data->saved_exit_latency;
 -      genpd->cpuidle_data->idle_state->exit_latency = usecs64;
 -}
 -
  static int genpd_power_on(struct generic_pm_domain *genpd, bool timed)
  {
        ktime_t time_start;
  
        genpd->power_on_latency_ns = elapsed_ns;
        genpd->max_off_time_changed = true;
 -      genpd_recalc_cpu_exit_latency(genpd);
        pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n",
                 genpd->name, "on", elapsed_ns);
  
@@@ -159,10 -213,10 +159,10 @@@ static int genpd_power_off(struct gener
  }
  
  /**
 - * genpd_queue_power_off_work - Queue up the execution of pm_genpd_poweroff().
 + * genpd_queue_power_off_work - Queue up the execution of genpd_poweroff().
   * @genpd: PM domait to power off.
   *
 - * Queue up the execution of pm_genpd_poweroff() unless it's already been done
 + * Queue up the execution of genpd_poweroff() unless it's already been done
   * before.
   */
  static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
        queue_work(pm_wq, &genpd->power_off_work);
  }
  
 +static int genpd_poweron(struct generic_pm_domain *genpd);
 +
  /**
 - * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
 + * __genpd_poweron - Restore power to a given PM domain and its masters.
   * @genpd: PM domain to power up.
   *
   * Restore power to @genpd and all of its masters so that it is possible to
   * resume a device belonging to it.
   */
 -static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
 +static int __genpd_poweron(struct generic_pm_domain *genpd)
  {
        struct gpd_link *link;
        int ret = 0;
            || (genpd->prepared_count > 0 && genpd->suspend_power_off))
                return 0;
  
 -      if (genpd->cpuidle_data) {
 -              cpuidle_pause_and_lock();
 -              genpd->cpuidle_data->idle_state->disabled = true;
 -              cpuidle_resume_and_unlock();
 -              goto out;
 -      }
 -
        /*
         * The list is guaranteed not to change while the loop below is being
         * executed, unless one of the masters' .power_on() callbacks fiddles
        list_for_each_entry(link, &genpd->slave_links, slave_node) {
                genpd_sd_counter_inc(link->master);
  
 -              ret = pm_genpd_poweron(link->master);
 +              ret = genpd_poweron(link->master);
                if (ret) {
                        genpd_sd_counter_dec(link->master);
                        goto err;
        if (ret)
                goto err;
  
 - out:
        genpd->status = GPD_STATE_ACTIVE;
        return 0;
  
  }
  
  /**
 - * pm_genpd_poweron - Restore power to a given PM domain and its masters.
 + * genpd_poweron - Restore power to a given PM domain and its masters.
   * @genpd: PM domain to power up.
   */
 -int pm_genpd_poweron(struct generic_pm_domain *genpd)
 +static int genpd_poweron(struct generic_pm_domain *genpd)
  {
        int ret;
  
        mutex_lock(&genpd->lock);
 -      ret = __pm_genpd_poweron(genpd);
 +      ret = __genpd_poweron(genpd);
        mutex_unlock(&genpd->lock);
        return ret;
  }
  
 -/**
 - * pm_genpd_name_poweron - Restore power to a given PM domain and its masters.
 - * @domain_name: Name of the PM domain to power up.
 - */
 -int pm_genpd_name_poweron(const char *domain_name)
 -{
 -      struct generic_pm_domain *genpd;
 -
 -      genpd = pm_genpd_lookup_name(domain_name);
 -      return genpd ? pm_genpd_poweron(genpd) : -EINVAL;
 -}
 -
  static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
  {
 -      return GENPD_DEV_TIMED_CALLBACK(genpd, int, save_state, dev,
 -                                      save_state_latency_ns, "state save");
 +      return GENPD_DEV_CALLBACK(genpd, int, save_state, dev);
  }
  
  static int genpd_restore_dev(struct generic_pm_domain *genpd,
 -                      struct device *dev, bool timed)
 +                      struct device *dev)
  {
 -      if (!timed)
 -              return GENPD_DEV_CALLBACK(genpd, int, restore_state, dev);
 -
 -      return GENPD_DEV_TIMED_CALLBACK(genpd, int, restore_state, dev,
 -                                      restore_state_latency_ns,
 -                                      "state restore");
 +      return GENPD_DEV_CALLBACK(genpd, int, restore_state, dev);
  }
  
  static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
  }
  
  /**
 - * pm_genpd_poweroff - Remove power from a given PM domain.
 + * genpd_poweroff - Remove power from a given PM domain.
   * @genpd: PM domain to power down.
 + * @is_async: PM domain is powered down from a scheduled work
   *
   * If all of the @genpd's devices have been suspended and all of its subdomains
   * have been powered down, remove power from @genpd.
   */
 -static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
 +static int genpd_poweroff(struct generic_pm_domain *genpd, bool is_async)
  {
        struct pm_domain_data *pdd;
        struct gpd_link *link;
                        not_suspended++;
        }
  
 -      if (not_suspended > genpd->in_progress)
 +      if (not_suspended > 1 || (not_suspended == 1 && is_async))
                return -EBUSY;
  
        if (genpd->gov && genpd->gov->power_down_ok) {
                        return -EAGAIN;
        }
  
 -      if (genpd->cpuidle_data) {
 -              /*
 -               * If cpuidle_data is set, cpuidle should turn the domain off
 -               * when the CPU in it is idle.  In that case we don't decrement
 -               * the subdomain counts of the master domains, so that power is
 -               * not removed from the current domain prematurely as a result
 -               * of cutting off the masters' power.
 -               */
 -              genpd->status = GPD_STATE_POWER_OFF;
 -              cpuidle_pause_and_lock();
 -              genpd->cpuidle_data->idle_state->disabled = false;
 -              cpuidle_resume_and_unlock();
 -              return 0;
 -      }
 -
        if (genpd->power_off) {
                int ret;
  
  
                /*
                 * If sd_count > 0 at this point, one of the subdomains hasn't
 -               * managed to call pm_genpd_poweron() for the master yet after
 -               * incrementing it.  In that case pm_genpd_poweron() will wait
 +               * managed to call genpd_poweron() for the master yet after
 +               * incrementing it.  In that case genpd_poweron() will wait
                 * for us to drop the lock, so we can call .power_off() and let
 -               * the pm_genpd_poweron() restore power for us (this shouldn't
 +               * the genpd_poweron() restore power for us (this shouldn't
                 * happen very often).
                 */
                ret = genpd_power_off(genpd, true);
@@@ -374,7 -466,7 +374,7 @@@ static void genpd_power_off_work_fn(str
        genpd = container_of(work, struct generic_pm_domain, power_off_work);
  
        mutex_lock(&genpd->lock);
 -      pm_genpd_poweroff(genpd);
 +      genpd_poweroff(genpd, true);
        mutex_unlock(&genpd->lock);
  }
  
@@@ -390,9 -482,6 +390,9 @@@ static int pm_genpd_runtime_suspend(str
  {
        struct generic_pm_domain *genpd;
        bool (*stop_ok)(struct device *__dev);
 +      struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
 +      ktime_t time_start;
 +      s64 elapsed_ns;
        int ret;
  
        dev_dbg(dev, "%s()\n", __func__);
        if (stop_ok && !stop_ok(dev))
                return -EBUSY;
  
 +      /* Measure suspend latency. */
 +      time_start = ktime_get();
 +
        ret = genpd_save_dev(genpd, dev);
        if (ret)
                return ret;
  
        ret = genpd_stop_dev(genpd, dev);
        if (ret) {
 -              genpd_restore_dev(genpd, dev, true);
 +              genpd_restore_dev(genpd, dev);
                return ret;
        }
  
 +      /* Update suspend latency value if the measured time exceeds it. */
 +      elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
 +      if (elapsed_ns > td->suspend_latency_ns) {
 +              td->suspend_latency_ns = elapsed_ns;
 +              dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
 +                      elapsed_ns);
 +              genpd->max_off_time_changed = true;
 +              td->constraint_changed = true;
 +      }
 +
        /*
         * If power.irq_safe is set, this routine will be run with interrupts
         * off, so it can't use mutexes.
                return 0;
  
        mutex_lock(&genpd->lock);
 -      genpd->in_progress++;
 -      pm_genpd_poweroff(genpd);
 -      genpd->in_progress--;
 +      genpd_poweroff(genpd, false);
        mutex_unlock(&genpd->lock);
  
        return 0;
  static int pm_genpd_runtime_resume(struct device *dev)
  {
        struct generic_pm_domain *genpd;
 +      struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
 +      ktime_t time_start;
 +      s64 elapsed_ns;
        int ret;
        bool timed = true;
  
        }
  
        mutex_lock(&genpd->lock);
 -      ret = __pm_genpd_poweron(genpd);
 +      ret = __genpd_poweron(genpd);
        mutex_unlock(&genpd->lock);
  
        if (ret)
                return ret;
  
   out:
 -      genpd_start_dev(genpd, dev, timed);
 -      genpd_restore_dev(genpd, dev, timed);
 +      /* Measure resume latency. */
 +      if (timed)
 +              time_start = ktime_get();
 +
 +      genpd_start_dev(genpd, dev);
 +      genpd_restore_dev(genpd, dev);
 +
 +      /* Update resume latency value if the measured time exceeds it. */
 +      if (timed) {
 +              elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
 +              if (elapsed_ns > td->resume_latency_ns) {
 +                      td->resume_latency_ns = elapsed_ns;
 +                      dev_dbg(dev, "resume latency exceeded, %lld ns\n",
 +                              elapsed_ns);
 +                      genpd->max_off_time_changed = true;
 +                      td->constraint_changed = true;
 +              }
 +      }
  
        return 0;
  }
@@@ -510,15 -569,15 +510,15 @@@ static int __init pd_ignore_unused_setu
  __setup("pd_ignore_unused", pd_ignore_unused_setup);
  
  /**
 - * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use.
 + * genpd_poweroff_unused - Power off all PM domains with no devices in use.
   */
 -void pm_genpd_poweroff_unused(void)
 +static int __init genpd_poweroff_unused(void)
  {
        struct generic_pm_domain *genpd;
  
        if (pd_ignore_unused) {
                pr_warn("genpd: Not disabling unused power domains\n");
 -              return;
 +              return 0;
        }
  
        mutex_lock(&gpd_list_lock);
                genpd_queue_power_off_work(genpd);
  
        mutex_unlock(&gpd_list_lock);
 -}
  
 -static int __init genpd_poweroff_unused(void)
 -{
 -      pm_genpd_poweroff_unused();
        return 0;
  }
  late_initcall(genpd_poweroff_unused);
@@@ -701,7 -764,7 +701,7 @@@ static int pm_genpd_prepare(struct devi
  
        /*
         * The PM domain must be in the GPD_STATE_ACTIVE state at this point,
 -       * so pm_genpd_poweron() will return immediately, but if the device
 +       * so genpd_poweron() will return immediately, but if the device
         * is suspended (e.g. it's been stopped by genpd_stop_dev()), we need
         * to make it operational.
         */
@@@ -827,7 -890,7 +827,7 @@@ static int pm_genpd_resume_noirq(struc
        pm_genpd_sync_poweron(genpd, true);
        genpd->suspended_count--;
  
 -      return genpd_start_dev(genpd, dev, true);
 +      return genpd_start_dev(genpd, dev);
  }
  
  /**
@@@ -955,8 -1018,7 +955,8 @@@ static int pm_genpd_thaw_noirq(struct d
        if (IS_ERR(genpd))
                return -EINVAL;
  
 -      return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev, true);
 +      return genpd->suspend_power_off ?
 +              0 : genpd_start_dev(genpd, dev);
  }
  
  /**
@@@ -1050,7 -1112,7 +1050,7 @@@ static int pm_genpd_restore_noirq(struc
  
        pm_genpd_sync_poweron(genpd, true);
  
 -      return genpd_start_dev(genpd, dev, true);
 +      return genpd_start_dev(genpd, dev);
  }
  
  /**
@@@ -1254,6 -1316,18 +1254,6 @@@ int __pm_genpd_add_device(struct generi
        return ret;
  }
  
 -/**
 - * __pm_genpd_name_add_device - Find I/O PM domain and add a device to it.
 - * @domain_name: Name of the PM domain to add the device to.
 - * @dev: Device to be added.
 - * @td: Set of PM QoS timing parameters to attach to the device.
 - */
 -int __pm_genpd_name_add_device(const char *domain_name, struct device *dev,
 -                             struct gpd_timing_data *td)
 -{
 -      return __pm_genpd_add_device(pm_genpd_lookup_name(domain_name), dev, td);
 -}
 -
  /**
   * pm_genpd_remove_device - Remove a device from an I/O PM domain.
   * @genpd: PM domain to remove the device from.
@@@ -1353,7 -1427,37 +1353,8 @@@ int pm_genpd_add_subdomain(struct gener
  
        return ret;
  }
+ EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain);
  
 -/**
 - * pm_genpd_add_subdomain_names - Add a subdomain to an I/O PM domain.
 - * @master_name: Name of the master PM domain to add the subdomain to.
 - * @subdomain_name: Name of the subdomain to be added.
 - */
 -int pm_genpd_add_subdomain_names(const char *master_name,
 -                               const char *subdomain_name)
 -{
 -      struct generic_pm_domain *master = NULL, *subdomain = NULL, *gpd;
 -
 -      if (IS_ERR_OR_NULL(master_name) || IS_ERR_OR_NULL(subdomain_name))
 -              return -EINVAL;
 -
 -      mutex_lock(&gpd_list_lock);
 -      list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
 -              if (!master && !strcmp(gpd->name, master_name))
 -                      master = gpd;
 -
 -              if (!subdomain && !strcmp(gpd->name, subdomain_name))
 -                      subdomain = gpd;
 -
 -              if (master && subdomain)
 -                      break;
 -      }
 -      mutex_unlock(&gpd_list_lock);
 -
 -      return pm_genpd_add_subdomain(master, subdomain);
 -}
 -
  /**
   * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
   * @genpd: Master PM domain to remove the subdomain from.
  
        return ret;
  }
+ EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
  
 -/**
 - * pm_genpd_attach_cpuidle - Connect the given PM domain with cpuidle.
 - * @genpd: PM domain to be connected with cpuidle.
 - * @state: cpuidle state this domain can disable/enable.
 - *
 - * Make a PM domain behave as though it contained a CPU core, that is, instead
 - * of calling its power down routine it will enable the given cpuidle state so
 - * that the cpuidle subsystem can power it down (if possible and desirable).
 - */
 -int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
 -{
 -      struct cpuidle_driver *cpuidle_drv;
 -      struct gpd_cpuidle_data *cpuidle_data;
 -      struct cpuidle_state *idle_state;
 -      int ret = 0;
 -
 -      if (IS_ERR_OR_NULL(genpd) || state < 0)
 -              return -EINVAL;
 -
 -      mutex_lock(&genpd->lock);
 -
 -      if (genpd->cpuidle_data) {
 -              ret = -EEXIST;
 -              goto out;
 -      }
 -      cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL);
 -      if (!cpuidle_data) {
 -              ret = -ENOMEM;
 -              goto out;
 -      }
 -      cpuidle_drv = cpuidle_driver_ref();
 -      if (!cpuidle_drv) {
 -              ret = -ENODEV;
 -              goto err_drv;
 -      }
 -      if (cpuidle_drv->state_count <= state) {
 -              ret = -EINVAL;
 -              goto err;
 -      }
 -      idle_state = &cpuidle_drv->states[state];
 -      if (!idle_state->disabled) {
 -              ret = -EAGAIN;
 -              goto err;
 -      }
 -      cpuidle_data->idle_state = idle_state;
 -      cpuidle_data->saved_exit_latency = idle_state->exit_latency;
 -      genpd->cpuidle_data = cpuidle_data;
 -      genpd_recalc_cpu_exit_latency(genpd);
 -
 - out:
 -      mutex_unlock(&genpd->lock);
 -      return ret;
 -
 - err:
 -      cpuidle_driver_unref();
 -
 - err_drv:
 -      kfree(cpuidle_data);
 -      goto out;
 -}
 -
 -/**
 - * pm_genpd_name_attach_cpuidle - Find PM domain and connect cpuidle to it.
 - * @name: Name of the domain to connect to cpuidle.
 - * @state: cpuidle state this domain can manipulate.
 - */
 -int pm_genpd_name_attach_cpuidle(const char *name, int state)
 -{
 -      return pm_genpd_attach_cpuidle(pm_genpd_lookup_name(name), state);
 -}
 -
 -/**
 - * pm_genpd_detach_cpuidle - Remove the cpuidle connection from a PM domain.
 - * @genpd: PM domain to remove the cpuidle connection from.
 - *
 - * Remove the cpuidle connection set up by pm_genpd_attach_cpuidle() from the
 - * given PM domain.
 - */
 -int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
 -{
 -      struct gpd_cpuidle_data *cpuidle_data;
 -      struct cpuidle_state *idle_state;
 -      int ret = 0;
 -
 -      if (IS_ERR_OR_NULL(genpd))
 -              return -EINVAL;
 -
 -      mutex_lock(&genpd->lock);
 -
 -      cpuidle_data = genpd->cpuidle_data;
 -      if (!cpuidle_data) {
 -              ret = -ENODEV;
 -              goto out;
 -      }
 -      idle_state = cpuidle_data->idle_state;
 -      if (!idle_state->disabled) {
 -              ret = -EAGAIN;
 -              goto out;
 -      }
 -      idle_state->exit_latency = cpuidle_data->saved_exit_latency;
 -      cpuidle_driver_unref();
 -      genpd->cpuidle_data = NULL;
 -      kfree(cpuidle_data);
 -
 - out:
 -      mutex_unlock(&genpd->lock);
 -      return ret;
 -}
 -
 -/**
 - * pm_genpd_name_detach_cpuidle - Find PM domain and disconnect cpuidle from it.
 - * @name: Name of the domain to disconnect cpuidle from.
 - */
 -int pm_genpd_name_detach_cpuidle(const char *name)
 -{
 -      return pm_genpd_detach_cpuidle(pm_genpd_lookup_name(name));
 -}
 -
  /* Default device callbacks for generic PM domains. */
  
  /**
@@@ -1467,6 -1690,7 +1469,6 @@@ void pm_genpd_init(struct generic_pm_do
        mutex_init(&genpd->lock);
        genpd->gov = gov;
        INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
 -      genpd->in_progress = 0;
        atomic_set(&genpd->sd_count, 0);
        genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE;
        genpd->device_count = 0;
@@@ -1801,7 -2025,7 +1803,7 @@@ int genpd_dev_pm_attach(struct device *
  
        dev->pm_domain->detach = genpd_dev_pm_detach;
        dev->pm_domain->sync = genpd_dev_pm_sync;
 -      ret = pm_genpd_poweron(pd);
 +      ret = genpd_poweron(pd);
  
  out:
        return ret ? -EPROBE_DEFER : 0;
diff --combined drivers/clk/Kconfig
index 67826167a0e0af6ebf5fcca662e04554ab89569d,57316528e9240ab9db0c5e2585ad79211e291467..c3e3a02f7f1f9b288ac93a524db3615f6abb72ae
@@@ -14,6 -14,7 +14,7 @@@ config COMMON_CL
        select HAVE_CLK_PREPARE
        select CLKDEV_LOOKUP
        select SRCU
+       select RATIONAL
        ---help---
          The common clock framework is a single definition of struct
          clk, useful across many platforms, as well as an
@@@ -59,16 -60,6 +60,16 @@@ config COMMON_CLK_RK80
          clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
          by control register.
  
 +config COMMON_CLK_SCPI
 +      tristate "Clock driver controlled via SCPI interface"
 +      depends on ARM_SCPI_PROTOCOL || COMPILE_TEST
 +        ---help---
 +        This driver provides support for clocks that are controlled
 +        by firmware that implements the SCPI interface.
 +
 +        This driver uses SCPI Message Protocol to interact with the
 +        firmware providing all the clock controls.
 +
  config COMMON_CLK_SI5351
        tristate "Clock driver for SiLabs 5351A/B/C"
        depends on I2C
          This driver supports Silicon Labs 5351A/B/C programmable clock
          generators.
  
+ config COMMON_CLK_SI514
+       tristate "Clock driver for SiLabs 514 devices"
+       depends on I2C
+       depends on OF
+       select REGMAP_I2C
+       help
+       ---help---
+         This driver supports the Silicon Labs 514 programmable clock
+         generator.
  config COMMON_CLK_SI570
        tristate "Clock driver for SiLabs 570 and compatible devices"
        depends on I2C
@@@ -123,7 -124,7 +134,7 @@@ config CLK_TWL604
  
  config COMMON_CLK_AXI_CLKGEN
        tristate "AXI clkgen driver"
-       depends on ARCH_ZYNQ || MICROBLAZE
+       depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
        help
        ---help---
          Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
  
  config CLK_QORIQ
        bool "Clock driver for Freescale QorIQ platforms"
-       depends on (PPC_E500MC || ARM || ARM64) && OF
 -      depends on (PPC_E500MC || ARM || COMPILE_TEST) && OF
++      depends on (PPC_E500MC || ARM || ARM64 || COMPILE_TEST) && OF
        ---help---
          This adds the clock driver support for Freescale QorIQ platforms
          using common clock framework.
  config COMMON_CLK_XGENE
        bool "Clock driver for APM XGene SoC"
        default y
-       depends on ARM64
+       depends on ARM64 || COMPILE_TEST
        ---help---
          Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
  
  config COMMON_CLK_KEYSTONE
        tristate "Clock drivers for Keystone based SOCs"
-       depends on ARCH_KEYSTONE && OF
+       depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF
        ---help---
            Supports clock drivers for Keystone based SOCs. These SOCs have local
          a power sleep control module that gate the clock to the IPs and PLLs.
diff --combined drivers/clk/Makefile
index 1ec1ce1849a72c84e64446769452d22a54fd3ae5,d3e1910eebaba6ed0bf765549582345d2470933e..820714c72d368e29fe211d1699c9a68202c98359
@@@ -36,8 -36,8 +36,9 @@@ obj-$(CONFIG_COMMON_CLK_PALMAS)               += clk
  obj-$(CONFIG_CLK_QORIQ)                       += clk-qoriq.o
  obj-$(CONFIG_COMMON_CLK_RK808)                += clk-rk808.o
  obj-$(CONFIG_COMMON_CLK_S2MPS11)      += clk-s2mps11.o
 +obj-$(CONFIG_COMMON_CLK_SCPI)           += clk-scpi.o
  obj-$(CONFIG_COMMON_CLK_SI5351)               += clk-si5351.o
+ obj-$(CONFIG_COMMON_CLK_SI514)                += clk-si514.o
  obj-$(CONFIG_COMMON_CLK_SI570)                += clk-si570.o
  obj-$(CONFIG_COMMON_CLK_CDCE925)      += clk-cdce925.o
  obj-$(CONFIG_ARCH_STM32)              += clk-stm32f4.o
@@@ -48,7 -48,7 +49,7 @@@ obj-$(CONFIG_COMMON_CLK_WM831X)               += clk
  obj-$(CONFIG_COMMON_CLK_XGENE)                += clk-xgene.o
  obj-$(CONFIG_COMMON_CLK_PWM)          += clk-pwm.o
  obj-$(CONFIG_COMMON_CLK_AT91)         += at91/
- obj-$(CONFIG_ARCH_BCM)                        += bcm/
+ obj-y                                 += bcm/
  obj-$(CONFIG_ARCH_BERLIN)             += berlin/
  obj-$(CONFIG_ARCH_HISI)                       += hisilicon/
  obj-$(CONFIG_ARCH_MXC)                        += imx/
index 72d2f3500db85ba5d27bf173af90d9689bc1b491,243f421abcb45815f2bd55a5bb22697346fac648..f144547cf76ca94767eac93de9e8d82a0b4d7c7d
@@@ -45,7 -45,7 +45,7 @@@
  #define REG_SDIO0XIN_CLKCTL   0x0158
  #define REG_SDIO1XIN_CLKCTL   0x015c
  
 -#define       MAX_CLKS 27
 +#define       MAX_CLKS 28
  static struct clk *clks[MAX_CLKS];
  static struct clk_onecell_data clk_data;
  static DEFINE_SPINLOCK(lock);
@@@ -283,7 -283,7 +283,7 @@@ static const struct berlin2_gate_data b
        { "usb2",       "perif",        13 },
        { "usb3",       "perif",        14 },
        { "pbridge",    "perif",        15, CLK_IGNORE_UNUSED },
-       { "sdio",       "perif",        16, CLK_IGNORE_UNUSED },
+       { "sdio",       "perif",        16 },
        { "nfc",        "perif",        18 },
        { "pcie",       "perif",        22 },
  };
@@@ -356,13 -356,13 +356,13 @@@ static void __init berlin2q_clock_setup
                            gd->bit_idx, 0, &lock);
        }
  
 -      /*
 -       * twdclk is derived from cpu/3
 -       * TODO: use cpupll until cpuclk is not available
 -       */
 +      /* cpuclk divider is fixed to 1 */
 +      clks[CLKID_CPU] =
 +              clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
 +                                        0, 1, 1);
 +      /* twdclk is derived from cpu/3 */
        clks[CLKID_TWD] =
 -              clk_register_fixed_factor(NULL, "twd", clk_names[CPUPLL],
 -                                        0, 1, 3);
 +              clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
  
        /* check for errors on leaf clocks */
        for (n = 0; n < MAX_CLKS; n++) {
index bc24e5a002e77cad874a0c010fc55046aa66b0f4,1c8162e5c1ce77b75c81054b9a30e18be3f94ed0..2685644826a06ed5a6f21240ad8af040bf4b0b9e
@@@ -41,12 -41,14 +41,14 @@@ static unsigned long rockchip_mmc_recal
  #define ROCKCHIP_MMC_DEGREE_MASK 0x3
  #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
  #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+ #define ROCKCHIP_MMC_INIT_STATE_RESET 0x1
+ #define ROCKCHIP_MMC_INIT_STATE_SHIFT 1
  
  #define PSECS_PER_SEC 1000000000000LL
  
  /*
 - * Each fine delay is between 40ps-80ps. Assume each fine delay is 60ps to
 - * simplify calculations. So 45degs could be anywhere between 33deg and 66deg.
 + * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
 + * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
   */
  #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
  
@@@ -69,7 -71,7 +71,7 @@@ static int rockchip_mmc_get_phase(struc
  
                delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
                delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
 -              degrees += delay_num * factor / 10000;
 +              degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
        }
  
        return degrees % 360;
@@@ -82,41 -84,25 +84,41 @@@ static int rockchip_mmc_set_phase(struc
        u8 nineties, remainder;
        u8 delay_num;
        u32 raw_value;
 -      u64 delay;
 -
 -      /* allow 22 to be 22.5 */
 -      degrees++;
 -      /* floor to 22.5 increment */
 -      degrees -= ((degrees) * 10 % 225) / 10;
 +      u32 delay;
  
        nineties = degrees / 90;
 -      /* 22.5 multiples */
 -      remainder = (degrees % 90) / 22;
 -
 -      delay = PSECS_PER_SEC;
 -      do_div(delay, rate);
 -      /* / 360 / 22.5 */
 -      do_div(delay, 16);
 -      do_div(delay, ROCKCHIP_MMC_DELAY_ELEMENT_PSEC);
 -
 +      remainder = (degrees % 90);
 +
 +      /*
 +       * Due to the inexact nature of the "fine" delay, we might
 +       * actually go non-monotonic.  We don't go _too_ monotonic
 +       * though, so we should be OK.  Here are options of how we may
 +       * work:
 +       *
 +       * Ideally we end up with:
 +       *   1.0, 2.0, ..., 69.0, 70.0, ...,  89.0, 90.0
 +       *
 +       * On one extreme (if delay is actually 44ps):
 +       *   .73, 1.5, ..., 50.6, 51.3, ...,  65.3, 90.0
 +       * The other (if delay is actually 77ps):
 +       *   1.3, 2.6, ..., 88.6. 89.8, ..., 114.0, 90
 +       *
 +       * It's possible we might make a delay that is up to 25
 +       * degrees off from what we think we're making.  That's OK
 +       * though because we should be REALLY far from any bad range.
 +       */
 +
 +      /*
 +       * Convert to delay; do a little extra work to make sure we
 +       * don't overflow 32-bit / 64-bit numbers.
 +       */
 +      delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
        delay *= remainder;
 -      delay_num = (u8) min(delay, 255ULL);
 +      delay = DIV_ROUND_CLOSEST(delay,
 +                      (rate / 1000) * 36 *
 +                              (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
 +
 +      delay_num = (u8) min_t(u32, delay, 255);
  
        raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
        raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
@@@ -159,6 -145,15 +161,15 @@@ struct clk *rockchip_clk_register_mmc(c
        mmc_clock->reg = reg;
        mmc_clock->shift = shift;
  
+       /*
+        * Assert init_state to soft reset the CLKGEN
+        * for mmc tuning phase and degree
+        */
+       if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT)
+               writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_RESET,
+                                    ROCKCHIP_MMC_INIT_STATE_RESET,
+                                    mmc_clock->shift), mmc_clock->reg);
        clk = clk_register(NULL, &mmc_clock->hw);
        if (IS_ERR(clk))
                goto err_free;
index a0a56e99882ac9ab028e290c3eb6be463e89e9dc,4abf21172625e81a7036dad77f90ea2d4158039c..3b09716ebda28227eebd52da5616c40245e490d5
@@@ -214,7 -214,7 +214,7 @@@ static void __init cpg_mstp_clocks_init
                        break;
  
                if (clkidx >= MSTP_MAX_CLOCKS) {
-                       pr_err("%s: invalid clock %s %s index %u)\n",
+                       pr_err("%s: invalid clock %s %s index %u\n",
                               __func__, np->name, name, clkidx);
                        continue;
                }
@@@ -259,10 -259,6 +259,10 @@@ int cpg_mstp_attach_dev(struct generic_
                                            "renesas,cpg-mstp-clocks"))
                        goto found;
  
 +              /* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock */
 +              if (!strcmp(clkspec.np->name, "zb_clk"))
 +                      goto found;
 +
                of_node_put(clkspec.np);
                i++;
        }
index a0cdbf35dcb19bd637632f55d514ad16d1588036,df3eddfa53a3b34bcd8d75b87225a31285f6d201..a5d319e4aae65dad90f64bafd33c2ad02bed7034
@@@ -63,9 -63,6 +63,9 @@@ struct dw8250_data 
        struct clk              *pclk;
        struct reset_control    *rst;
        struct uart_8250_dma    dma;
 +
 +      unsigned int            skip_autocfg:1;
 +      unsigned int            uart_16550_compatible:1;
  };
  
  #define BYT_PRV_CLK                   0x800
@@@ -227,10 -224,6 +227,6 @@@ static void dw8250_set_termios(struct u
        if (IS_ERR(d->clk) || !old)
                goto out;
  
-       /* Not requesting clock rates below 1.8432Mhz */
-       if (baud < 115200)
-               baud = 115200;
        clk_disable_unprepare(d->clk);
        rate = clk_round_rate(d->clk, baud * 16);
        ret = clk_set_rate(d->clk, rate);
@@@ -247,77 -240,24 +243,77 @@@ out
        serial8250_do_set_termios(p, termios, old);
  }
  
 -static bool dw8250_dma_filter(struct dma_chan *chan, void *param)
 +/*
 + * dw8250_fallback_dma_filter will prevent the UART from getting just any free
 + * channel on platforms that have DMA engines, but don't have any channels
 + * assigned to the UART.
 + *
 + * REVISIT: This is a work around for limitation in the DMA Engine API. Once the
 + * core problem is fixed, this function is no longer needed.
 + */
 +static bool dw8250_fallback_dma_filter(struct dma_chan *chan, void *param)
  {
        return false;
  }
  
 -static void dw8250_setup_port(struct uart_8250_port *up)
 +static bool dw8250_idma_filter(struct dma_chan *chan, void *param)
 +{
 +      return param == chan->device->dev->parent;
 +}
 +
 +static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
  {
 -      struct uart_port        *p = &up->port;
 -      u32                     reg = readl(p->membase + DW_UART_UCV);
 +      if (p->dev->of_node) {
 +              struct device_node *np = p->dev->of_node;
 +              int id;
 +
 +              /* get index of serial line, if found in DT aliases */
 +              id = of_alias_get_id(np, "serial");
 +              if (id >= 0)
 +                      p->line = id;
 +#ifdef CONFIG_64BIT
 +              if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) {
 +                      p->serial_in = dw8250_serial_inq;
 +                      p->serial_out = dw8250_serial_outq;
 +                      p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
 +                      p->type = PORT_OCTEON;
 +                      data->usr_reg = 0x27;
 +                      data->skip_autocfg = true;
 +              }
 +#endif
 +      } else if (has_acpi_companion(p->dev)) {
 +              p->iotype = UPIO_MEM32;
 +              p->regshift = 2;
 +              p->serial_in = dw8250_serial_in32;
 +              p->set_termios = dw8250_set_termios;
 +              /* So far none of there implement the Busy Functionality */
 +              data->uart_16550_compatible = true;
 +      }
 +
 +      /* Platforms with iDMA */
 +      if (platform_get_resource_byname(to_platform_device(p->dev),
 +                                       IORESOURCE_MEM, "lpss_priv")) {
 +              p->set_termios = dw8250_set_termios;
 +              data->dma.rx_param = p->dev->parent;
 +              data->dma.tx_param = p->dev->parent;
 +              data->dma.fn = dw8250_idma_filter;
 +      }
 +}
 +
 +static void dw8250_setup_port(struct uart_port *p)
 +{
 +      struct uart_8250_port *up = up_to_u8250p(p);
 +      u32 reg;
  
        /*
         * If the Component Version Register returns zero, we know that
         * ADDITIONAL_FEATURES are not enabled. No need to go any further.
         */
 +      reg = readl(p->membase + DW_UART_UCV);
        if (!reg)
                return;
  
 -      dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n",
 +      dev_dbg(p->dev, "Designware UART version %c.%c%c\n",
                (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);
  
        reg = readl(p->membase + DW_UART_CPR);
                p->type = PORT_16550A;
                p->flags |= UPF_FIXED_TYPE;
                p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
 -              up->tx_loadsz = p->fifosize;
                up->capabilities = UART_CAP_FIFO;
        }
  
                up->capabilities |= UART_CAP_AFE;
  }
  
 -static int dw8250_probe_of(struct uart_port *p,
 -                         struct dw8250_data *data)
 +static int dw8250_probe(struct platform_device *pdev)
  {
 -      struct device_node      *np = p->dev->of_node;
 -      struct uart_8250_port *up = up_to_u8250p(p);
 -      u32                     val;
 -      bool has_ucv = true;
 -      int id;
 +      struct uart_8250_port uart = {};
 +      struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +      int irq = platform_get_irq(pdev, 0);
 +      struct uart_port *p = &uart.port;
 +      struct dw8250_data *data;
 +      int err;
 +      u32 val;
  
 -#ifdef CONFIG_64BIT
 -      if (of_device_is_compatible(np, "cavium,octeon-3860-uart")) {
 -              p->serial_in = dw8250_serial_inq;
 -              p->serial_out = dw8250_serial_outq;
 -              p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
 -              p->type = PORT_OCTEON;
 -              data->usr_reg = 0x27;
 -              has_ucv = false;
 -      } else
 -#endif
 -      if (!of_property_read_u32(np, "reg-io-width", &val)) {
 -              switch (val) {
 -              case 1:
 -                      break;
 -              case 4:
 -                      p->iotype = UPIO_MEM32;
 -                      p->serial_in = dw8250_serial_in32;
 -                      p->serial_out = dw8250_serial_out32;
 -                      break;
 -              default:
 -                      dev_err(p->dev, "unsupported reg-io-width (%u)\n", val);
 -                      return -EINVAL;
 -              }
 +      if (!regs) {
 +              dev_err(&pdev->dev, "no registers defined\n");
 +              return -EINVAL;
        }
 -      if (has_ucv)
 -              dw8250_setup_port(up);
  
 -      /* if we have a valid fifosize, try hooking up DMA here */
 -      if (p->fifosize) {
 -              up->dma = &data->dma;
 -
 -              up->dma->rxconf.src_maxburst = p->fifosize / 4;
 -              up->dma->txconf.dst_maxburst = p->fifosize / 4;
 +      if (irq < 0) {
 +              if (irq != -EPROBE_DEFER)
 +                      dev_err(&pdev->dev, "cannot get irq\n");
 +              return irq;
        }
  
 -      if (!of_property_read_u32(np, "reg-shift", &val))
 +      spin_lock_init(&p->lock);
 +      p->mapbase      = regs->start;
 +      p->irq          = irq;
 +      p->handle_irq   = dw8250_handle_irq;
 +      p->pm           = dw8250_do_pm;
 +      p->type         = PORT_8250;
 +      p->flags        = UPF_SHARE_IRQ | UPF_FIXED_PORT;
 +      p->dev          = &pdev->dev;
 +      p->iotype       = UPIO_MEM;
 +      p->serial_in    = dw8250_serial_in;
 +      p->serial_out   = dw8250_serial_out;
 +
 +      p->membase = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
 +      if (!p->membase)
 +              return -ENOMEM;
 +
 +      data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 +      if (!data)
 +              return -ENOMEM;
 +
 +      data->dma.fn = dw8250_fallback_dma_filter;
 +      data->usr_reg = DW_UART_USR;
 +      p->private_data = data;
 +
 +      data->uart_16550_compatible = device_property_read_bool(p->dev,
 +                                              "snps,uart-16550-compatible");
 +
 +      err = device_property_read_u32(p->dev, "reg-shift", &val);
 +      if (!err)
                p->regshift = val;
  
 -      /* get index of serial line, if found in DT aliases */
 -      id = of_alias_get_id(np, "serial");
 -      if (id >= 0)
 -              p->line = id;
 +      err = device_property_read_u32(p->dev, "reg-io-width", &val);
 +      if (!err && val == 4) {
 +              p->iotype = UPIO_MEM32;
 +              p->serial_in = dw8250_serial_in32;
 +              p->serial_out = dw8250_serial_out32;
 +      }
  
 -      if (of_property_read_bool(np, "dcd-override")) {
 +      if (device_property_read_bool(p->dev, "dcd-override")) {
                /* Always report DCD as active */
                data->msr_mask_on |= UART_MSR_DCD;
                data->msr_mask_off |= UART_MSR_DDCD;
        }
  
 -      if (of_property_read_bool(np, "dsr-override")) {
 +      if (device_property_read_bool(p->dev, "dsr-override")) {
                /* Always report DSR as active */
                data->msr_mask_on |= UART_MSR_DSR;
                data->msr_mask_off |= UART_MSR_DDSR;
        }
  
 -      if (of_property_read_bool(np, "cts-override")) {
 +      if (device_property_read_bool(p->dev, "cts-override")) {
                /* Always report CTS as active */
                data->msr_mask_on |= UART_MSR_CTS;
                data->msr_mask_off |= UART_MSR_DCTS;
        }
  
 -      if (of_property_read_bool(np, "ri-override")) {
 +      if (device_property_read_bool(p->dev, "ri-override")) {
                /* Always report Ring indicator as inactive */
                data->msr_mask_off |= UART_MSR_RI;
                data->msr_mask_off |= UART_MSR_TERI;
        }
  
 -      return 0;
 -}
 -
 -static bool dw8250_idma_filter(struct dma_chan *chan, void *param)
 -{
 -      struct device *dev = param;
 -
 -      if (dev != chan->device->dev->parent)
 -              return false;
 -
 -      return true;
 -}
 -
 -static int dw8250_probe_acpi(struct uart_8250_port *up,
 -                           struct dw8250_data *data)
 -{
 -      struct uart_port *p = &up->port;
 -
 -      dw8250_setup_port(up);
 -
 -      p->iotype = UPIO_MEM32;
 -      p->serial_in = dw8250_serial_in32;
 -      p->serial_out = dw8250_serial_out32;
 -      p->regshift = 2;
 -
 -      /* Platforms with iDMA */
 -      if (platform_get_resource_byname(to_platform_device(up->port.dev),
 -                                       IORESOURCE_MEM, "lpss_priv")) {
 -              data->dma.rx_param = up->port.dev->parent;
 -              data->dma.tx_param = up->port.dev->parent;
 -              data->dma.fn = dw8250_idma_filter;
 -      }
 -
 -      up->dma = &data->dma;
 -      up->dma->rxconf.src_maxburst = p->fifosize / 4;
 -      up->dma->txconf.dst_maxburst = p->fifosize / 4;
 -
 -      up->port.set_termios = dw8250_set_termios;
 -
 -      return 0;
 -}
 -
 -static int dw8250_probe(struct platform_device *pdev)
 -{
 -      struct uart_8250_port uart = {};
 -      struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      int irq = platform_get_irq(pdev, 0);
 -      struct dw8250_data *data;
 -      int err;
 -
 -      if (!regs) {
 -              dev_err(&pdev->dev, "no registers defined\n");
 -              return -EINVAL;
 -      }
 -
 -      if (irq < 0) {
 -              if (irq != -EPROBE_DEFER)
 -                      dev_err(&pdev->dev, "cannot get irq\n");
 -              return irq;
 -      }
 -
 -      spin_lock_init(&uart.port.lock);
 -      uart.port.mapbase = regs->start;
 -      uart.port.irq = irq;
 -      uart.port.handle_irq = dw8250_handle_irq;
 -      uart.port.pm = dw8250_do_pm;
 -      uart.port.type = PORT_8250;
 -      uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
 -      uart.port.dev = &pdev->dev;
 -
 -      uart.port.membase = devm_ioremap(&pdev->dev, regs->start,
 -                                       resource_size(regs));
 -      if (!uart.port.membase)
 -              return -ENOMEM;
 -
 -      data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 -      if (!data)
 -              return -ENOMEM;
 -
 -      data->usr_reg = DW_UART_USR;
 -
        /* Always ask for fixed clock rate from a property. */
 -      device_property_read_u32(&pdev->dev, "clock-frequency",
 -                               &uart.port.uartclk);
 +      device_property_read_u32(p->dev, "clock-frequency", &p->uartclk);
  
        /* If there is separate baudclk, get the rate from it. */
        data->clk = devm_clk_get(&pdev->dev, "baudclk");
                        dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n",
                                 err);
                else
 -                      uart.port.uartclk = clk_get_rate(data->clk);
 +                      p->uartclk = clk_get_rate(data->clk);
        }
  
        /* If no clock rate is defined, fail. */
 -      if (!uart.port.uartclk) {
 +      if (!p->uartclk) {
                dev_err(&pdev->dev, "clock rate not defined\n");
                return -EINVAL;
        }
        if (!IS_ERR(data->rst))
                reset_control_deassert(data->rst);
  
 -      data->dma.rx_param = data;
 -      data->dma.tx_param = data;
 -      data->dma.fn = dw8250_dma_filter;
 +      dw8250_quirks(p, data);
  
 -      uart.port.iotype = UPIO_MEM;
 -      uart.port.serial_in = dw8250_serial_in;
 -      uart.port.serial_out = dw8250_serial_out;
 -      uart.port.private_data = data;
 +      /* If the Busy Functionality is not implemented, don't handle it */
 +      if (data->uart_16550_compatible) {
 +              p->serial_out = NULL;
 +              p->handle_irq = NULL;
 +      }
  
 -      if (pdev->dev.of_node) {
 -              err = dw8250_probe_of(&uart.port, data);
 -              if (err)
 -                      goto err_reset;
 -      } else if (ACPI_HANDLE(&pdev->dev)) {
 -              err = dw8250_probe_acpi(&uart, data);
 -              if (err)
 -                      goto err_reset;
 -      } else {
 -              err = -ENODEV;
 -              goto err_reset;
 +      if (!data->skip_autocfg)
 +              dw8250_setup_port(p);
 +
 +      /* If we have a valid fifosize, try hooking up DMA */
 +      if (p->fifosize) {
 +              data->dma.rxconf.src_maxburst = p->fifosize / 4;
 +              data->dma.txconf.dst_maxburst = p->fifosize / 4;
 +              uart.dma = &data->dma;
        }
  
        data->line = serial8250_register_8250_port(&uart);