--- /dev/null
+From b110547e586eb5825bc1d04aa9147bff83b57672 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Fri, 18 May 2012 12:26:19 -0500
+Subject: ARM: OMAP2+: OPP: Fix to ensure check of right oppdef after bad one
+
+From: Nishanth Menon <nm@ti.com>
+
+commit b110547e586eb5825bc1d04aa9147bff83b57672 upstream.
+
+Commit 9fa2df6b90786301b175e264f5fa9846aba81a65
+(ARM: OMAP2+: OPP: allow OPP enumeration to continue if device is not present)
+makes the logic:
+for (i = 0; i < opp_def_size; i++) {
+ <snip>
+ if (!oh || !oh->od) {
+ <snip>
+ continue;
+ }
+<snip>
+opp_def++;
+}
+
+In short, the moment we hit a "Bad OPP", we end up looping the list
+comparing against the bad opp definition pointer for the rest of the
+iteration count. Instead, increment opp_def in the for loop itself
+and allow continue to be used in code without much thought so that
+we check the next set of OPP definition pointers :)
+
+Cc: Steve Sakoman <steve@sakoman.com>
+Cc: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-omap2/opp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/arm/mach-omap2/opp.c
++++ b/arch/arm/mach-omap2/opp.c
+@@ -53,7 +53,7 @@ int __init omap_init_opp_table(struct om
+ omap_table_init = 1;
+
+ /* Lets now register with OPP library */
+- for (i = 0; i < opp_def_size; i++) {
++ for (i = 0; i < opp_def_size; i++, opp_def++) {
+ struct omap_hwmod *oh;
+ struct device *dev;
+
+@@ -86,7 +86,6 @@ int __init omap_init_opp_table(struct om
+ __func__, opp_def->freq,
+ opp_def->hwmod_name, i, r);
+ }
+- opp_def++;
+ }
+
+ return 0;
--- /dev/null
+From 940f5d47e2f2e1fa00443921a0abf4822335b54d Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bvanassche@acm.org>
+Date: Fri, 29 Jun 2012 15:34:26 +0000
+Subject: SCSI: Avoid dangling pointer in scsi_requeue_command()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+commit 940f5d47e2f2e1fa00443921a0abf4822335b54d upstream.
+
+When we call scsi_unprep_request() the command associated with the request
+gets destroyed and therefore drops its reference on the device. If this was
+the only reference, the device may get released and we end up with a NULL
+pointer deref when we call blk_requeue_request.
+
+Reported-by: Mike Christie <michaelc@cs.wisc.edu>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
+Reviewed-by: Tejun Heo <tj@kernel.org>
+[jejb: enhance commend and add commit log for stable]
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/scsi_lib.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -481,15 +481,26 @@ void scsi_requeue_run_queue(struct work_
+ */
+ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
+ {
++ struct scsi_device *sdev = cmd->device;
+ struct request *req = cmd->request;
+ unsigned long flags;
+
++ /*
++ * We need to hold a reference on the device to avoid the queue being
++ * killed after the unlock and before scsi_run_queue is invoked which
++ * may happen because scsi_unprep_request() puts the command which
++ * releases its reference on the device.
++ */
++ get_device(&sdev->sdev_gendev);
++
+ spin_lock_irqsave(q->queue_lock, flags);
+ scsi_unprep_request(req);
+ blk_requeue_request(q, req);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ scsi_run_queue(q);
++
++ put_device(&sdev->sdev_gendev);
+ }
+
+ void scsi_next_command(struct scsi_cmnd *cmd)
--- /dev/null
+From 57fc2e335fd3c2f898ee73570dc81426c28dc7b4 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Thu, 21 Jun 2012 23:25:32 -0700
+Subject: SCSI: fix eh wakeup (scsi_schedule_eh vs scsi_restart_operations)
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 57fc2e335fd3c2f898ee73570dc81426c28dc7b4 upstream.
+
+Rapid ata hotplug on a libsas controller results in cases where libsas
+is waiting indefinitely on eh to perform an ata probe.
+
+A race exists between scsi_schedule_eh() and scsi_restart_operations()
+in the case when scsi_restart_operations() issues i/o to other devices
+in the sas domain. When this happens the host state transitions from
+SHOST_RECOVERY (set by scsi_schedule_eh) back to SHOST_RUNNING and
+->host_busy is non-zero so we put the eh thread to sleep even though
+->host_eh_scheduled is active.
+
+Before putting the error handler to sleep we need to check if the
+host_state needs to return to SHOST_RECOVERY for another trip through
+eh. Since i/o that is released by scsi_restart_operations has been
+blocked for at least one eh cycle, this implementation allows those
+i/o's to run before another eh cycle starts to discourage hung task
+timeouts.
+
+Reported-by: Tom Jackson <thomas.p.jackson@intel.com>
+Tested-by: Tom Jackson <thomas.p.jackson@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/scsi_error.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -1665,6 +1665,20 @@ static void scsi_restart_operations(stru
+ * requests are started.
+ */
+ scsi_run_host_queues(shost);
++
++ /*
++ * if eh is active and host_eh_scheduled is pending we need to re-run
++ * recovery. we do this check after scsi_run_host_queues() to allow
++ * everything pent up since the last eh run a chance to make forward
++ * progress before we sync again. Either we'll immediately re-run
++ * recovery or scsi_device_unbusy() will wake us again when these
++ * pending commands complete.
++ */
++ spin_lock_irqsave(shost->host_lock, flags);
++ if (shost->host_eh_scheduled)
++ if (scsi_host_set_state(shost, SHOST_RECOVERY))
++ WARN_ON(scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY));
++ spin_unlock_irqrestore(shost->host_lock, flags);
+ }
+
+ /**
--- /dev/null
+From 3b661a92e869ebe2358de8f4b3230ad84f7fce51 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Thu, 21 Jun 2012 23:47:28 -0700
+Subject: SCSI: fix hot unplug vs async scan race
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 3b661a92e869ebe2358de8f4b3230ad84f7fce51 upstream.
+
+The following crash results from cases where the end_device has been
+removed before scsi_sysfs_add_sdev has had a chance to run.
+
+ BUG: unable to handle kernel NULL pointer dereference at 0000000000000098
+ IP: [<ffffffff8115e100>] sysfs_create_dir+0x32/0xb6
+ ...
+ Call Trace:
+ [<ffffffff8125e4a8>] kobject_add_internal+0x120/0x1e3
+ [<ffffffff81075149>] ? trace_hardirqs_on+0xd/0xf
+ [<ffffffff8125e641>] kobject_add_varg+0x41/0x50
+ [<ffffffff8125e70b>] kobject_add+0x64/0x66
+ [<ffffffff8131122b>] device_add+0x12d/0x63a
+ [<ffffffff814b65ea>] ? _raw_spin_unlock_irqrestore+0x47/0x56
+ [<ffffffff8107de15>] ? module_refcount+0x89/0xa0
+ [<ffffffff8132f348>] scsi_sysfs_add_sdev+0x4e/0x28a
+ [<ffffffff8132dcbb>] do_scan_async+0x9c/0x145
+
+...teach scsi_sysfs_add_devices() to check for deleted devices() before
+trying to add them, and teach scsi_remove_target() how to remove targets
+that have not been added via device_add().
+
+Reported-by: Dariusz Majchrzak <dariusz.majchrzak@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/scsi_scan.c | 3 +++
+ drivers/scsi/scsi_sysfs.c | 41 ++++++++++++++++++++++++++---------------
+ 2 files changed, 29 insertions(+), 15 deletions(-)
+
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -1710,6 +1710,9 @@ static void scsi_sysfs_add_devices(struc
+ {
+ struct scsi_device *sdev;
+ shost_for_each_device(sdev, shost) {
++ /* target removed before the device could be added */
++ if (sdev->sdev_state == SDEV_DEL)
++ continue;
+ if (!scsi_host_scan_allowed(shost) ||
+ scsi_sysfs_add_sdev(sdev) != 0)
+ __scsi_remove_device(sdev);
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -962,7 +962,6 @@ static void __scsi_remove_target(struct
+ struct scsi_device *sdev;
+
+ spin_lock_irqsave(shost->host_lock, flags);
+- starget->reap_ref++;
+ restart:
+ list_for_each_entry(sdev, &shost->__devices, siblings) {
+ if (sdev->channel != starget->channel ||
+@@ -976,14 +975,6 @@ static void __scsi_remove_target(struct
+ goto restart;
+ }
+ spin_unlock_irqrestore(shost->host_lock, flags);
+- scsi_target_reap(starget);
+-}
+-
+-static int __remove_child (struct device * dev, void * data)
+-{
+- if (scsi_is_target_device(dev))
+- __scsi_remove_target(to_scsi_target(dev));
+- return 0;
+ }
+
+ /**
+@@ -996,14 +987,34 @@ static int __remove_child (struct device
+ */
+ void scsi_remove_target(struct device *dev)
+ {
+- if (scsi_is_target_device(dev)) {
+- __scsi_remove_target(to_scsi_target(dev));
+- return;
++ struct Scsi_Host *shost = dev_to_shost(dev->parent);
++ struct scsi_target *starget, *found;
++ unsigned long flags;
++
++ restart:
++ found = NULL;
++ spin_lock_irqsave(shost->host_lock, flags);
++ list_for_each_entry(starget, &shost->__targets, siblings) {
++ if (starget->state == STARGET_DEL)
++ continue;
++ if (starget->dev.parent == dev || &starget->dev == dev) {
++ found = starget;
++ found->reap_ref++;
++ break;
++ }
+ }
++ spin_unlock_irqrestore(shost->host_lock, flags);
+
+- get_device(dev);
+- device_for_each_child(dev, NULL, __remove_child);
+- put_device(dev);
++ if (found) {
++ __scsi_remove_target(found);
++ scsi_target_reap(found);
++ /* in the case where @dev has multiple starget children,
++ * continue removing.
++ *
++ * FIXME: does such a case exist?
++ */
++ goto restart;
++ }
+ }
+ EXPORT_SYMBOL(scsi_remove_target);
+
--- /dev/null
+From 26f2f199ff150d8876b2641c41e60d1c92d2fb81 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Thu, 21 Jun 2012 23:36:15 -0700
+Subject: SCSI: libsas: continue revalidation
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 26f2f199ff150d8876b2641c41e60d1c92d2fb81 upstream.
+
+Continue running revalidation until no more broadcast devices are
+discovered. Fixes cases where re-discovery completes too early in a
+domain with multiple expanders with pending re-discovery events.
+Servicing BCNs can get backed up behind error recovery.
+
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/libsas/sas_expander.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -1972,9 +1972,7 @@ int sas_ex_revalidate_domain(struct doma
+ struct domain_device *dev = NULL;
+
+ res = sas_find_bcast_dev(port_dev, &dev);
+- if (res)
+- goto out;
+- if (dev) {
++ while (res == 0 && dev) {
+ struct expander_device *ex = &dev->ex_dev;
+ int i = 0, phy_id;
+
+@@ -1986,8 +1984,10 @@ int sas_ex_revalidate_domain(struct doma
+ res = sas_rediscover(dev, phy_id);
+ i = phy_id + 1;
+ } while (i < ex->num_phys);
++
++ dev = NULL;
++ res = sas_find_bcast_dev(port_dev, &dev);
+ }
+-out:
+ return res;
+ }
+
--- /dev/null
+From b17caa174a7e1fd2e17b26e210d4ee91c4c28b37 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Thu, 21 Jun 2012 23:36:20 -0700
+Subject: SCSI: libsas: fix sas_discover_devices return code handling
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit b17caa174a7e1fd2e17b26e210d4ee91c4c28b37 upstream.
+
+commit 198439e4 [SCSI] libsas: do not set res = 0 in sas_ex_discover_dev()
+commit 19252de6 [SCSI] libsas: fix wide port hotplug issues
+
+The above commits seem to have confused the return value of
+sas_ex_discover_dev which is non-zero on failure and
+sas_ex_join_wide_port which just indicates short circuiting discovery on
+already established ports. The result is random discovery failures
+depending on configuration.
+
+Calls to sas_ex_join_wide_port are the source of the trouble as its
+return value is errantly assigned to 'res'. Convert it to bool and stop
+returning its result up the stack.
+
+Tested-by: Dan Melnic <dan.melnic@amd.com>
+Reported-by: Dan Melnic <dan.melnic@amd.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Jack Wang <jack_wang@usish.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/libsas/sas_expander.c | 39 +++++++++++--------------------------
+ 1 file changed, 12 insertions(+), 27 deletions(-)
+
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -770,7 +770,7 @@ static struct domain_device *sas_ex_disc
+ }
+
+ /* See if this phy is part of a wide port */
+-static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
++static bool sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
+ {
+ struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
+ int i;
+@@ -786,11 +786,11 @@ static int sas_ex_join_wide_port(struct
+ sas_port_add_phy(ephy->port, phy->phy);
+ phy->port = ephy->port;
+ phy->phy_state = PHY_DEVICE_DISCOVERED;
+- return 0;
++ return true;
+ }
+ }
+
+- return -ENODEV;
++ return false;
+ }
+
+ static struct domain_device *sas_ex_discover_expander(
+@@ -928,8 +928,7 @@ static int sas_ex_discover_dev(struct do
+ return res;
+ }
+
+- res = sas_ex_join_wide_port(dev, phy_id);
+- if (!res) {
++ if (sas_ex_join_wide_port(dev, phy_id)) {
+ SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
+ phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
+ return res;
+@@ -974,8 +973,7 @@ static int sas_ex_discover_dev(struct do
+ if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
+ SAS_ADDR(child->sas_addr)) {
+ ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
+- res = sas_ex_join_wide_port(dev, i);
+- if (!res)
++ if (sas_ex_join_wide_port(dev, i))
+ SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
+ i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr));
+
+@@ -1838,32 +1836,20 @@ static int sas_discover_new(struct domai
+ {
+ struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
+ struct domain_device *child;
+- bool found = false;
+- int res, i;
++ int res;
+
+ SAS_DPRINTK("ex %016llx phy%d new device attached\n",
+ SAS_ADDR(dev->sas_addr), phy_id);
+ res = sas_ex_phy_discover(dev, phy_id);
+ if (res)
+- goto out;
+- /* to support the wide port inserted */
+- for (i = 0; i < dev->ex_dev.num_phys; i++) {
+- struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i];
+- if (i == phy_id)
+- continue;
+- if (SAS_ADDR(ex_phy_temp->attached_sas_addr) ==
+- SAS_ADDR(ex_phy->attached_sas_addr)) {
+- found = true;
+- break;
+- }
+- }
+- if (found) {
+- sas_ex_join_wide_port(dev, phy_id);
++ return res;
++
++ if (sas_ex_join_wide_port(dev, phy_id))
+ return 0;
+- }
++
+ res = sas_ex_discover_devices(dev, phy_id);
+- if (!res)
+- goto out;
++ if (res)
++ return res;
+ list_for_each_entry(child, &dev->ex_dev.children, siblings) {
+ if (SAS_ADDR(child->sas_addr) ==
+ SAS_ADDR(ex_phy->attached_sas_addr)) {
+@@ -1873,7 +1859,6 @@ static int sas_discover_new(struct domai
+ break;
+ }
+ }
+-out:
+ return res;
+ }
+
powerpc-ftrace-fix-assembly-trampoline-register-usage.patch
powerpc-add-memory-attribute-for-mfmsr.patch
powerpc-fix-wrong-divisor-in-usecs_to_cputime.patch
+scsi-libsas-continue-revalidation.patch
+scsi-libsas-fix-sas_discover_devices-return-code-handling.patch
+scsi-fix-eh-wakeup-scsi_schedule_eh-vs-scsi_restart_operations.patch
+scsi-fix-hot-unplug-vs-async-scan-race.patch
+scsi-avoid-dangling-pointer-in-scsi_requeue_command.patch
+arm-omap2-opp-fix-to-ensure-check-of-right-oppdef-after-bad-one.patch