Merge tag 'for_3.7-fixes-pm' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman...
authorTony Lindgren <tony@atomide.com>
Mon, 8 Oct 2012 22:57:41 +0000 (15:57 -0700)
committerTony Lindgren <tony@atomide.com>
Mon, 8 Oct 2012 22:57:41 +0000 (15:57 -0700)
OMAP PM related fixes for v3.7-rc

1  2 
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/sr_device.c
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/omap_device.c
drivers/power/avs/smartreflex.c

  #include <linux/regulator/machine.h>
  #include <linux/i2c/twl.h>
  
 -#include <mach/hardware.h>
  #include <asm/mach-types.h>
  #include <asm/mach/arch.h>
  #include <asm/mach/map.h>
  #include <asm/mach/flash.h>
  
 -#include <plat/board.h>
  #include "common.h"
  #include <video/omapdss.h>
  #include <video/omap-panel-tfp410.h>
  #include <plat/gpmc.h>
 -#include <plat/nand.h>
 +#include <linux/platform_data/mtd-nand-omap2.h>
  #include <plat/usb.h>
  #include <plat/omap_device.h>
  
@@@ -295,6 -297,9 +295,6 @@@ static int beagle_twl_gpio_setup(struc
  }
  
  static struct twl4030_gpio_platform_data beagle_gpio_data = {
 -      .gpio_base      = OMAP_MAX_GPIO_LINES,
 -      .irq_base       = TWL4030_GPIO_IRQ_BASE,
 -      .irq_end        = TWL4030_GPIO_IRQ_END,
        .use_leds       = true,
        .pullups        = BIT(1),
        .pulldowns      = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
@@@ -461,7 -466,7 +461,7 @@@ static void __init beagle_opp_init(void
                mpu_dev = omap_device_get_by_hwmod_name("mpu");
                iva_dev = omap_device_get_by_hwmod_name("iva");
  
-               if (!mpu_dev || !iva_dev) {
+               if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) {
                        pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
                                __func__, mpu_dev, iva_dev);
                        return;
diff --combined arch/arm/mach-omap2/pm.c
@@@ -80,8 -80,7 +80,8 @@@ static void __init omap2_init_processor
  
  int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
  {
 -      if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
 +      if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
 +          !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
                clkdm_allow_idle(clkdm);
        else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
                 atomic_read(&clkdm->usecount) == 0)
@@@ -177,7 -176,7 +177,7 @@@ static int __init omap2_set_init_voltag
        }
  
        voltdm = voltdm_lookup(vdd_name);
-       if (IS_ERR(voltdm)) {
+       if (!voltdm) {
                pr_err("%s: unable to get vdd pointer for vdd_%s\n",
                        __func__, vdd_name);
                goto exit;
                goto exit;
        }
  
 -      freq = clk->rate;
 +      freq = clk_get_rate(clk);
        clk_put(clk);
  
        rcu_read_lock();
        bootup_volt = opp_get_voltage(opp);
        rcu_read_unlock();
        if (!bootup_volt) {
 -              pr_err("%s: unable to find voltage corresponding "
 -                      "to the bootup OPP for vdd_%s\n", __func__, vdd_name);
 +              pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n",
 +                     __func__, vdd_name);
                goto exit;
        }
  
@@@ -104,15 -104,16 +104,15 @@@ static int __init sr_dev_init(struct om
  
        sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL);
        if (!sr_data) {
 -              pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n",
 -                      __func__, oh->name);
 +              pr_err("%s: Unable to allocate memory for %s sr_data\n",
 +                     __func__, oh->name);
                return -ENOMEM;
        }
  
        sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
        if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
 -              pr_err("%s: No voltage domain specified for %s."
 -                              "Cannot initialize\n", __func__,
 -                                      oh->name);
 +              pr_err("%s: No voltage domain specified for %s. Cannot initialize\n",
 +                     __func__, oh->name);
                goto exit;
        }
  
        sr_data->senp_mod = 0x1;
  
        sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
-       if (IS_ERR(sr_data->voltdm)) {
+       if (!sr_data->voltdm) {
                pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
                        __func__, sr_dev_attr->sensor_voltdm_name);
                goto exit;
  
        omap_voltage_get_volttable(sr_data->voltdm, &volt_data);
        if (!volt_data) {
 -              pr_warning("%s: No Voltage table registered fo VDD%d."
 -                      "Something really wrong\n\n", __func__, i + 1);
 +              pr_err("%s: No Voltage table registered for VDD%d\n",
 +                     __func__, i + 1);
                goto exit;
        }
  
@@@ -25,7 -25,6 +25,7 @@@ config ARCH_OMAP2PLU
        bool "TI OMAP2/3/4"
        select CLKDEV_LOOKUP
        select GENERIC_IRQ_CHIP
 +      select SPARSE_IRQ
        select OMAP_DM_TIMER
        select USE_OF
        select PROC_DEVICETREE if PROC_FS
@@@ -42,12 -41,14 +42,13 @@@ config OMAP_DEBUG_DEVICE
          For debug cards on TI reference boards.
  
  config OMAP_DEBUG_LEDS
 -      bool
 +      def_bool y if NEW_LEDS
        depends on OMAP_DEBUG_DEVICES
 -      default y if LEDS_CLASS
  
  config POWER_AVS_OMAP
        bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
        depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM
+       select POWER_SUPPLY
        help
          Say Y to enable AVS(Adaptive Voltage Scaling)
          support on OMAP containing the version 1 or
@@@ -1,3 -1,4 +1,3 @@@
 -
  /*
   * omap_device implementation
   *
@@@ -152,19 -153,21 +152,19 @@@ static int _omap_device_activate(struc
                act_lat = timespec_to_ns(&c);
  
                dev_dbg(&od->pdev->dev,
 -                      "omap_device: pm_lat %d: activate: elapsed time "
 -                      "%llu nsec\n", od->pm_lat_level, act_lat);
 +                      "omap_device: pm_lat %d: activate: elapsed time %llu nsec\n",
 +                      od->pm_lat_level, act_lat);
  
                if (act_lat > odpl->activate_lat) {
                        odpl->activate_lat_worst = act_lat;
                        if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
                                odpl->activate_lat = act_lat;
                                dev_dbg(&od->pdev->dev,
 -                                      "new worst case activate latency "
 -                                      "%d: %llu\n",
 +                                      "new worst case activate latency %d: %llu\n",
                                        od->pm_lat_level, act_lat);
                        } else
                                dev_warn(&od->pdev->dev,
 -                                       "activate latency %d "
 -                                       "higher than exptected. (%llu > %d)\n",
 +                                       "activate latency %d higher than expected. (%llu > %d)\n",
                                         od->pm_lat_level, act_lat,
                                         odpl->activate_lat);
                }
@@@ -217,19 -220,21 +217,19 @@@ static int _omap_device_deactivate(stru
                deact_lat = timespec_to_ns(&c);
  
                dev_dbg(&od->pdev->dev,
 -                      "omap_device: pm_lat %d: deactivate: elapsed time "
 -                      "%llu nsec\n", od->pm_lat_level, deact_lat);
 +                      "omap_device: pm_lat %d: deactivate: elapsed time %llu nsec\n",
 +                      od->pm_lat_level, deact_lat);
  
                if (deact_lat > odpl->deactivate_lat) {
                        odpl->deactivate_lat_worst = deact_lat;
                        if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
                                odpl->deactivate_lat = deact_lat;
                                dev_dbg(&od->pdev->dev,
 -                                      "new worst case deactivate latency "
 -                                      "%d: %llu\n",
 +                                      "new worst case deactivate latency %d: %llu\n",
                                        od->pm_lat_level, deact_lat);
                        } else
                                dev_warn(&od->pdev->dev,
 -                                       "deactivate latency %d "
 -                                       "higher than exptected. (%llu > %d)\n",
 +                                       "deactivate latency %d higher than expected. (%llu > %d)\n",
                                         od->pm_lat_level, deact_lat,
                                         odpl->deactivate_lat);
                }
@@@ -261,10 -266,10 +261,10 @@@ static void _add_clkdev(struct omap_dev
                return;
        }
  
 -      r = omap_clk_get_by_name(clk_name);
 +      r = clk_get(NULL, clk_name);
        if (IS_ERR(r)) {
                dev_err(&od->pdev->dev,
 -                      "omap_clk_get_by_name for %s failed\n", clk_name);
 +                      "clk_get for %s failed\n", clk_name);
                return;
        }
  
@@@ -365,14 -370,6 +365,14 @@@ static int omap_device_build_from_dt(st
                goto odbfd_exit1;
        }
  
 +      /* Fix up missing resource names */
 +      for (i = 0; i < pdev->num_resources; i++) {
 +              struct resource *r = &pdev->resource[i];
 +
 +              if (r->name == NULL)
 +                      r->name = dev_name(&pdev->dev);
 +      }
 +
        if (of_get_property(node, "ti,no_idle_on_suspend", NULL))
                omap_device_disable_idle_on_suspend(pdev);
  
@@@ -388,21 -385,17 +388,21 @@@ static int _omap_device_notifier_call(s
                                      unsigned long event, void *dev)
  {
        struct platform_device *pdev = to_platform_device(dev);
 +      struct omap_device *od;
  
        switch (event) {
 -      case BUS_NOTIFY_ADD_DEVICE:
 -              if (pdev->dev.of_node)
 -                      omap_device_build_from_dt(pdev);
 -              break;
 -
        case BUS_NOTIFY_DEL_DEVICE:
                if (pdev->archdata.od)
                        omap_device_delete(pdev->archdata.od);
                break;
 +      case BUS_NOTIFY_ADD_DEVICE:
 +              if (pdev->dev.of_node)
 +                      omap_device_build_from_dt(pdev);
 +              /* fall through */
 +      default:
 +              od = to_omap_device(pdev);
 +              if (od)
 +                      od->_driver_status = event;
        }
  
        return NOTIFY_DONE;
@@@ -456,8 -449,8 +456,8 @@@ static int omap_device_count_resources(
        for (i = 0; i < od->hwmods_cnt; i++)
                c += omap_hwmod_count_resources(od->hwmods[i]);
  
 -      pr_debug("omap_device: %s: counted %d total resources across %d "
 -               "hwmods\n", od->pdev->name, c, od->hwmods_cnt);
 +      pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
 +               od->pdev->name, c, od->hwmods_cnt);
  
        return c;
  }
@@@ -492,33 -485,6 +492,33 @@@ static int omap_device_fill_resources(s
        return 0;
  }
  
 +/**
 + * _od_fill_dma_resources - fill in array of struct resource with dma resources
 + * @od: struct omap_device *
 + * @res: pointer to an array of struct resource to be filled in
 + *
 + * Populate one or more empty struct resource pointed to by @res with
 + * the dma resource data for this omap_device @od.  Used by
 + * omap_device_alloc() after calling omap_device_count_resources().
 + *
 + * Ideally this function would not be needed at all.  If we have
 + * mechanism to get dma resources from DT.
 + *
 + * Returns 0.
 + */
 +static int _od_fill_dma_resources(struct omap_device *od,
 +                                    struct resource *res)
 +{
 +      int i, r;
 +
 +      for (i = 0; i < od->hwmods_cnt; i++) {
 +              r = omap_hwmod_fill_dma_resources(od->hwmods[i], res);
 +              res += r;
 +      }
 +
 +      return 0;
 +}
 +
  /**
   * omap_device_alloc - allocate an omap_device
   * @pdev: platform_device that will be included in this omap_device
@@@ -558,44 -524,24 +558,44 @@@ struct omap_device *omap_device_alloc(s
        od->hwmods = hwmods;
        od->pdev = pdev;
  
 +      res_count = omap_device_count_resources(od);
        /*
 -       * HACK: Ideally the resources from DT should match, and hwmod
 -       * should just add the missing ones. Since the name is not
 -       * properly populated by DT, stick to hwmod resources only.
 +       * DT Boot:
 +       *   OF framework will construct the resource structure (currently
 +       *   does for MEM & IRQ resource) and we should respect/use these
 +       *   resources, killing hwmod dependency.
 +       *   If pdev->num_resources > 0, we assume that MEM & IRQ resources
 +       *   have been allocated by OF layer already (through DTB).
 +       *
 +       * Non-DT Boot:
 +       *   Here, pdev->num_resources = 0, and we should get all the
 +       *   resources from hwmod.
 +       *
 +       * TODO: Once DMA resource is available from OF layer, we should
 +       *   kill filling any resources from hwmod.
         */
 -      if (pdev->num_resources && pdev->resource)
 -              dev_warn(&pdev->dev, "%s(): resources already allocated %d\n",
 -                      __func__, pdev->num_resources);
 -
 -      res_count = omap_device_count_resources(od);
 -      if (res_count > 0) {
 -              dev_dbg(&pdev->dev, "%s(): resources allocated from hwmod %d\n",
 -                      __func__, res_count);
 +      if (res_count > pdev->num_resources) {
 +              /* Allocate resources memory to account for new resources */
                res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
                if (!res)
                        goto oda_exit3;
  
 -              omap_device_fill_resources(od, res);
 +              /*
 +               * If pdev->num_resources > 0, then assume that,
 +               * MEM and IRQ resources will only come from DT and only
 +               * fill DMA resource from hwmod layer.
 +               */
 +              if (pdev->num_resources && pdev->resource) {
 +                      dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n",
 +                              __func__, res_count);
 +                      memcpy(res, pdev->resource,
 +                             sizeof(struct resource) * pdev->num_resources);
 +                      _od_fill_dma_resources(od, &res[pdev->num_resources]);
 +              } else {
 +                      dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
 +                              __func__, res_count);
 +                      omap_device_fill_resources(od, res);
 +              }
  
                ret = platform_device_add_resources(pdev, res, res_count);
                kfree(res);
@@@ -725,7 -671,7 +725,7 @@@ struct platform_device __init *omap_dev
                dev_set_name(&pdev->dev, "%s", pdev->name);
  
        od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt);
-       if (!od)
+       if (IS_ERR(od))
                goto odbs_exit1;
  
        ret = platform_device_add_data(pdev, pdata, pdata_len);
@@@ -806,10 -752,6 +806,10 @@@ static int _od_suspend_noirq(struct dev
        struct omap_device *od = to_omap_device(pdev);
        int ret;
  
 +      /* Don't attempt late suspend on a driver that is not bound */
 +      if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER)
 +              return 0;
 +
        ret = pm_generic_suspend_noirq(dev);
  
        if (!ret && !pm_runtime_status_suspended(dev)) {
@@@ -982,61 -924,6 +982,61 @@@ int omap_device_shutdown(struct platfor
        return ret;
  }
  
 +/**
 + * omap_device_assert_hardreset - set a device's hardreset line
 + * @pdev: struct platform_device * to reset
 + * @name: const char * name of the reset line
 + *
 + * Set the hardreset line identified by @name on the IP blocks
 + * associated with the hwmods backing the platform_device @pdev.  All
 + * of the hwmods associated with @pdev must have the same hardreset
 + * line linked to them for this to work.  Passes along the return value
 + * of omap_hwmod_assert_hardreset() in the event of any failure, or
 + * returns 0 upon success.
 + */
 +int omap_device_assert_hardreset(struct platform_device *pdev, const char *name)
 +{
 +      struct omap_device *od = to_omap_device(pdev);
 +      int ret = 0;
 +      int i;
 +
 +      for (i = 0; i < od->hwmods_cnt; i++) {
 +              ret = omap_hwmod_assert_hardreset(od->hwmods[i], name);
 +              if (ret)
 +                      break;
 +      }
 +
 +      return ret;
 +}
 +
 +/**
 + * omap_device_deassert_hardreset - release a device's hardreset line
 + * @pdev: struct platform_device * to reset
 + * @name: const char * name of the reset line
 + *
 + * Release the hardreset line identified by @name on the IP blocks
 + * associated with the hwmods backing the platform_device @pdev.  All
 + * of the hwmods associated with @pdev must have the same hardreset
 + * line linked to them for this to work.  Passes along the return
 + * value of omap_hwmod_deassert_hardreset() in the event of any
 + * failure, or returns 0 upon success.
 + */
 +int omap_device_deassert_hardreset(struct platform_device *pdev,
 +                                 const char *name)
 +{
 +      struct omap_device *od = to_omap_device(pdev);
 +      int ret = 0;
 +      int i;
 +
 +      for (i = 0; i < od->hwmods_cnt; i++) {
 +              ret = omap_hwmod_deassert_hardreset(od->hwmods[i], name);
 +              if (ret)
 +                      break;
 +      }
 +
 +      return ret;
 +}
 +
  /**
   * omap_device_align_pm_lat - activate/deactivate device to match wakeup lat lim
   * @od: struct omap_device *
@@@ -1238,41 -1125,3 +1238,41 @@@ static int __init omap_device_init(void
        return 0;
  }
  core_initcall(omap_device_init);
 +
 +/**
 + * omap_device_late_idle - idle devices without drivers
 + * @dev: struct device * associated with omap_device
 + * @data: unused
 + *
 + * Check the driver bound status of this device, and idle it
 + * if there is no driver attached.
 + */
 +static int __init omap_device_late_idle(struct device *dev, void *data)
 +{
 +      struct platform_device *pdev = to_platform_device(dev);
 +      struct omap_device *od = to_omap_device(pdev);
 +
 +      if (!od)
 +              return 0;
 +
 +      /*
 +       * If omap_device state is enabled, but has no driver bound,
 +       * idle it.
 +       */
 +      if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
 +              if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
 +                      dev_warn(dev, "%s: enabled but no driver.  Idling\n",
 +                               __func__);
 +                      omap_device_idle(pdev);
 +              }
 +      }
 +
 +      return 0;
 +}
 +
 +static int __init omap_device_late_init(void)
 +{
 +      bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
 +      return 0;
 +}
 +late_initcall(omap_device_late_init);
@@@ -27,8 -27,6 +27,8 @@@
  #include <linux/pm_runtime.h>
  #include <linux/power/smartreflex.h>
  
 +#include <plat/cpu.h>
 +
  #define SMARTREFLEX_NAME_LEN  16
  #define NVALUE_NAME_LEN               40
  #define SR_DISABLE_TIMEOUT    200
@@@ -930,7 -928,7 +930,7 @@@ static int __init omap_sr_probe(struct 
        if (!sr_info->base) {
                dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
                ret = -ENOMEM;
-               goto err_release_region;
+               goto err_free_name;
        }
  
        if (irq)
                dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
                        __func__);
                ret = PTR_ERR(sr_info->dbg_dir);
-               goto err_free_name;
+               goto err_debugfs;
        }
  
        (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
  
  err_debugfs:
        debugfs_remove_recursive(sr_info->dbg_dir);
- err_free_name:
-       kfree(sr_info->name);
  err_iounmap:
        list_del(&sr_info->node);
        iounmap(sr_info->base);
+ err_free_name:
+       kfree(sr_info->name);
  err_release_region:
        release_mem_region(mem->start, resource_size(mem));
  err_free_devinfo: