Merge "msm: defconfig: Disable section mismatch=y" into msm-3.4
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 1bb69b5..4e50ce5 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -5133,6 +5133,81 @@
&asoc_msm_dai1,
};
+/* qseecom bus scaling */
+static struct msm_bus_vectors qseecom_clks_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = 0,
+ .ab = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = 0,
+ .ab = 0,
+ },
+};
+
+static struct msm_bus_vectors qseecom_enable_dfab_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = (492 * 8) * 1000000UL,
+ .ab = (492 * 8) * 100000UL,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = 0,
+ .ab = 0,
+ },
+};
+
+static struct msm_bus_vectors qseecom_enable_sfpb_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ib = 0,
+ .ab = 0,
+ },
+ {
+ .src = MSM_BUS_MASTER_SPDM,
+ .dst = MSM_BUS_SLAVE_SPDM,
+ .ib = (64 * 8) * 1000000UL,
+ .ab = (64 * 8) * 100000UL,
+ },
+};
+
+static struct msm_bus_paths qseecom_hw_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(qseecom_clks_init_vectors),
+ qseecom_clks_init_vectors,
+ },
+ {
+ ARRAY_SIZE(qseecom_enable_dfab_vectors),
+ qseecom_enable_sfpb_vectors,
+ },
+ {
+ ARRAY_SIZE(qseecom_enable_sfpb_vectors),
+ qseecom_enable_sfpb_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata qseecom_bus_pdata = {
+ .usecase = qseecom_hw_bus_scale_usecases,
+ .num_usecases = ARRAY_SIZE(qseecom_hw_bus_scale_usecases),
+ .name = "qsee",
+};
+
+static struct platform_device qseecom_device = {
+ .name = "qseecom",
+ .id = -1,
+ .dev = {
+ .platform_data = &qseecom_bus_pdata,
+ },
+};
+
static struct platform_device *surf_devices[] __initdata = {
&msm8x60_device_acpuclk,
&msm_device_smd,
@@ -5141,6 +5216,7 @@
&msm_pil_modem,
&msm_pil_tzapps,
&msm_pil_dsps,
+ &qseecom_device,
#ifdef CONFIG_I2C_QUP
&msm_gsbi3_qup_i2c_device,
&msm_gsbi4_qup_i2c_device,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index fa91249..76f2926 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4017,6 +4017,7 @@
.dbg_name = "tv_src_div_clk",
.ops = &clk_ops_cdiv,
CLK_INIT(tv_src_div_clk.c),
+ .rate = ULONG_MAX,
},
};
@@ -4423,6 +4424,7 @@
.dbg_name = #i "_clk", \
.ops = &clk_ops_cdiv, \
CLK_INIT(i##_clk.c), \
+ .rate = ULONG_MAX, \
}, \
}
@@ -4442,6 +4444,7 @@
.dbg_name = #i "_clk", \
.ops = &clk_ops_cdiv, \
CLK_INIT(i##_clk.c), \
+ .rate = ULONG_MAX, \
}, \
}
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index da7dca7..8389b58 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3022,6 +3022,7 @@
.dbg_name = #i "_clk", \
.ops = &clk_ops_cdiv, \
CLK_INIT(i##_clk.c), \
+ .rate = ULONG_MAX, \
}, \
}
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index f7ccb35..b2d83d2 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1175,6 +1175,7 @@
.dbg_name = #i "_clk", \
.ops = &clk_ops_cdiv, \
CLK_INIT(i##_clk.c), \
+ .rate = ULONG_MAX, \
}, \
}
@@ -1194,6 +1195,7 @@
.dbg_name = #i "_clk", \
.ops = &clk_ops_cdiv, \
CLK_INIT(i##_clk.c), \
+ .rate = ULONG_MAX, \
}, \
}
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index d5afe8d..e8e56b8 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -141,7 +141,6 @@
static uint32_t pil_ref_cnt;
static DEFINE_MUTEX(pil_access_lock);
-static DEFINE_MUTEX(send_msg_lock);
static DEFINE_MUTEX(qsee_bw_mutex);
static DEFINE_MUTEX(qsee_sfpb_bw_mutex);
static DEFINE_MUTEX(app_access_lock);
@@ -1447,24 +1446,24 @@
}
case QSEECOM_IOCTL_SEND_CMD_REQ: {
/* Only one client allowed here at a time */
- mutex_lock(&send_msg_lock);
+ mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
ret = qseecom_send_cmd(data, argp);
atomic_dec(&data->ioctl_count);
wake_up_all(&data->abort_wq);
- mutex_unlock(&send_msg_lock);
+ mutex_unlock(&app_access_lock);
if (ret)
pr_err("failed qseecom_send_cmd: %d\n", ret);
break;
}
case QSEECOM_IOCTL_SEND_MODFD_CMD_REQ: {
/* Only one client allowed here at a time */
- mutex_lock(&send_msg_lock);
+ mutex_lock(&app_access_lock);
atomic_inc(&data->ioctl_count);
ret = qseecom_send_modfd_cmd(data, argp);
atomic_dec(&data->ioctl_count);
wake_up_all(&data->abort_wq);
- mutex_unlock(&send_msg_lock);
+ mutex_unlock(&app_access_lock);
if (ret)
pr_err("failed qseecom_send_cmd: %d\n", ret);
break;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 0659b79..03bcc7c 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -3188,6 +3188,9 @@
pm_runtime_get_noresume(dev);
goto out;
}
+ } else if (dev->power.runtime_status == RPM_RESUMING) {
+ pm_runtime_get_noresume(dev);
+ goto out;
}
rc = pm_runtime_get_sync(dev);
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 73c042d..600913f 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -47,6 +47,8 @@
#define AMUX_TRIM_2 0x322
#define TEST_PROGRAM_REV 0x339
+#define TEMP_SOC_STORAGE 0x107
+
enum pmic_bms_interrupts {
PM8921_BMS_SBI_WRITE_OK,
PM8921_BMS_CC_THR,
@@ -134,8 +136,10 @@
struct timeval t;
int last_uuc_uah;
int enable_fcc_learning;
+ int shutdown_soc;
};
+static int shutdown_soc_invalid;
static struct pm8921_bms_chip *the_chip;
#define DEFAULT_RBATT_MOHMS 128
@@ -1455,6 +1459,71 @@
return soc;
}
+#define MAX_SHUTDOWN_ADJUST_SECONDS 1800
+static int adjust_for_shutdown_soc(struct pm8921_bms_chip *chip, int soc)
+{
+ struct timespec uptime;
+ int val;
+
+ /* value of zero means the shutdown soc should not be used */
+ if (chip->shutdown_soc == 0)
+ return soc;
+
+ if (shutdown_soc_invalid) {
+ chip->shutdown_soc = 0;
+ return soc;
+ }
+
+ do_posix_clock_monotonic_gettime(&uptime);
+
+ if (uptime.tv_sec >= MAX_SHUTDOWN_ADJUST_SECONDS) {
+ /*
+ * adjusted for a long time now, switch to reporting the
+ * calculated soc
+ */
+ chip->shutdown_soc = 0;
+ return soc;
+ }
+
+ val = ((MAX_SHUTDOWN_ADJUST_SECONDS - uptime.tv_sec)
+ * chip->shutdown_soc
+ + uptime.tv_sec * soc);
+ val /= MAX_SHUTDOWN_ADJUST_SECONDS;
+ pr_debug("shutdown_soc = %d, adj soc = %d, calc soc = %d\n",
+ chip->shutdown_soc, val, soc);
+
+ return val;
+}
+
+static void backup_soc(struct pm8921_bms_chip *chip, int last_soc)
+{
+ /* TODO: if 0x107 is free for all variants 8917, 8038 etc */
+ pm8xxx_writeb(the_chip->dev->parent, TEMP_SOC_STORAGE, last_soc);
+}
+
+static void read_shutdown_soc(struct pm8921_bms_chip *chip)
+{
+ int rc;
+ u8 temp;
+
+ rc = pm8xxx_readb(chip->dev->parent, TEMP_SOC_STORAGE, &temp);
+ if (rc)
+ pr_err("failed to read addr = %d %d\n", TEMP_SOC_STORAGE, rc);
+ else
+ chip->shutdown_soc = temp;
+
+ pr_debug("shutdown_soc = %d\n", chip->shutdown_soc);
+}
+
+void pm8921_bms_invalidate_shutdown_soc(void)
+{
+ pr_debug("Invalidating shutdown soc - the battery was removed\n");
+ shutdown_soc_invalid = 1;
+ if (the_chip)
+ the_chip->shutdown_soc = 0;
+}
+EXPORT_SYMBOL(pm8921_bms_invalidate_shutdown_soc);
+
/*
* Remaining Usable Charge = remaining_charge (charge at ocv instance)
* - coloumb counter charge
@@ -1469,6 +1538,7 @@
int remaining_charge_uah, soc;
int cc_uah;
int rbatt;
+ int shutdown_adjusted_soc;
calculate_soc_params(chip, raw, batt_temp, chargecycles,
&fcc_uah,
@@ -1534,9 +1604,12 @@
last_soc);
}
- pr_debug("Reported SOC = %u%%\n", last_soc);
- return last_soc;
+ shutdown_adjusted_soc = adjust_for_shutdown_soc(chip, last_soc);
+ backup_soc(chip, shutdown_adjusted_soc);
+
+ return shutdown_adjusted_soc;
}
+
#define MIN_DELTA_625_UV 1000
static void calib_hkadc(struct pm8921_bms_chip *chip)
{
@@ -2629,6 +2702,8 @@
goto free_irqs;
}
+ read_shutdown_soc(chip);
+
platform_set_drvdata(pdev, chip);
the_chip = chip;
create_debugfs_entries(chip);
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index a1561f0..a2eb39e 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -3296,13 +3296,29 @@
}
}
+#define VREF_BATT_THERM_FORCE_ON BIT(7)
+static void detect_battery_removal(struct pm8921_chg_chip *chip)
+{
+ u8 temp;
+
+ pm8xxx_readb(chip->dev->parent, CHG_CNTRL, &temp);
+ pr_debug("upon restart CHG_CNTRL = 0x%x\n", temp);
+
+ if (!(temp & VREF_BATT_THERM_FORCE_ON))
+ /*
+ * batt therm force on bit is battery backed and is default 0
+ * The charger sets this bit at init time. If this bit is found
+ * 0 that means the battery was removed. Tell the bms about it
+ */
+ pm8921_bms_invalidate_shutdown_soc();
+}
+
#define ENUM_TIMER_STOP_BIT BIT(1)
#define BOOT_DONE_BIT BIT(6)
#define CHG_BATFET_ON_BIT BIT(3)
#define CHG_VCP_EN BIT(0)
#define CHG_BAT_TEMP_DIS_BIT BIT(2)
#define SAFE_CURRENT_MA 1500
-#define VREF_BATT_THERM_FORCE_ON BIT(7)
static int __devinit pm8921_chg_hw_init(struct pm8921_chg_chip *chip)
{
int rc;
@@ -3311,6 +3327,8 @@
/* forcing 19p2mhz before accessing any charger registers */
pm8921_chg_force_19p2mhz_clk(chip);
+ detect_battery_removal(chip);
+
rc = pm_chg_masked_write(chip, SYS_CONFIG_2,
BOOT_DONE_BIT, BOOT_DONE_BIT);
if (rc) {
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 78d32a7..1e49be4 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -394,7 +394,8 @@
#ifdef CONFIG_CMA
/* The below functions must be run on a range from a single zone. */
-extern int alloc_contig_range(unsigned long start, unsigned long end);
+extern int alloc_contig_range(unsigned long start, unsigned long end,
+ unsigned migratetype);
extern void free_contig_range(unsigned long pfn, unsigned nr_pages);
/* CMA stuff */
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 90c2d99..bbd032d 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -200,6 +200,13 @@
* pm8921_bms_get_rbatt - function to get the battery resistance in mOhm.
*/
int pm8921_bms_get_rbatt(void);
+/**
+ * pm8921_bms_invalidate_shutdown_soc - function to notify the bms driver that
+ * the battery was replaced between reboot
+ * and so it should not use the shutdown
+ * soc stored in a coincell backed register
+ */
+void pm8921_bms_invalidate_shutdown_soc(void);
#else
static inline int pm8921_bms_get_vsense_avg(int *result)
{
@@ -235,6 +242,9 @@
{
return -EINVAL;
}
+static inline void pm8921_bms_invalidate_shutdown_soc(void)
+{
+}
#endif
#endif
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index 051c1b1..3bdcab3 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -3,7 +3,7 @@
/*
* Changes migrate type in [start_pfn, end_pfn) to be MIGRATE_ISOLATE.
- * If specified range includes migrate types other than MOVABLE,
+ * If specified range includes migrate types other than MOVABLE or CMA,
* this will fail with -EBUSY.
*
* For isolating all pages in the range finally, the caller have to
@@ -11,27 +11,27 @@
* test it.
*/
extern int
-start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn);
+start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
+ unsigned migratetype);
/*
* Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE.
* target range is [start_pfn, end_pfn)
*/
extern int
-undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn);
+undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
+ unsigned migratetype);
/*
- * test all pages in [start_pfn, end_pfn)are isolated or not.
+ * Test all pages in [start_pfn, end_pfn) are isolated or not.
*/
-extern int
-test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn);
+int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn);
/*
- * Internal funcs.Changes pageblock's migrate type.
- * Please use make_pagetype_isolated()/make_pagetype_movable().
+ * Internal functions. Changes pageblock's migrate type.
*/
extern int set_migratetype_isolate(struct page *page);
-extern void unset_migratetype_isolate(struct page *page);
+extern void unset_migratetype_isolate(struct page *page, unsigned migratetype);
#endif
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 97cc273..c99ad4e 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1404,7 +1404,7 @@
/* Not a free page */
ret = 1;
}
- unset_migratetype_isolate(p);
+ unset_migratetype_isolate(p, MIGRATE_MOVABLE);
unlock_memory_hotplug();
return ret;
}
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index b031f96..a0e1819 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -959,7 +959,7 @@
nr_pages = end_pfn - start_pfn;
/* set above range as isolated */
- ret = start_isolate_page_range(start_pfn, end_pfn);
+ ret = start_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
if (ret)
goto out;
@@ -1024,7 +1024,7 @@
We cannot do rollback at this point. */
offline_isolated_pages(start_pfn, end_pfn);
/* reset pagetype flags and makes migrate type to be MOVABLE */
- undo_isolate_page_range(start_pfn, end_pfn);
+ undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
/* removal success */
if (offlined_pages > zone->present_pages)
zone->present_pages = 0;
@@ -1056,7 +1056,7 @@
start_pfn, end_pfn);
memory_notify(MEM_CANCEL_OFFLINE, &arg);
/* pushback to free area */
- undo_isolate_page_range(start_pfn, end_pfn);
+ undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
out:
unlock_memory_hotplug();
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5eeace2..a17921f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2138,16 +2138,13 @@
}
#endif /* CONFIG_COMPACTION */
-/* The really slow allocator path where we enter direct reclaim */
-static inline struct page *
-__alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order,
- struct zonelist *zonelist, enum zone_type high_zoneidx,
- nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone,
- int migratetype, unsigned long *did_some_progress)
+/* Perform direct synchronous page reclaim */
+static int
+__perform_reclaim(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist,
+ nodemask_t *nodemask)
{
- struct page *page = NULL;
struct reclaim_state reclaim_state;
- bool drained = false;
+ int progress;
cond_resched();
@@ -2158,7 +2155,7 @@
reclaim_state.reclaimed_slab = 0;
current->reclaim_state = &reclaim_state;
- *did_some_progress = try_to_free_pages(zonelist, order, gfp_mask, nodemask);
+ progress = try_to_free_pages(zonelist, order, gfp_mask, nodemask);
current->reclaim_state = NULL;
lockdep_clear_current_reclaim_state();
@@ -2166,6 +2163,21 @@
cond_resched();
+ return progress;
+}
+
+/* The really slow allocator path where we enter direct reclaim */
+static inline struct page *
+__alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order,
+ struct zonelist *zonelist, enum zone_type high_zoneidx,
+ nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone,
+ int migratetype, unsigned long *did_some_progress)
+{
+ struct page *page = NULL;
+ bool drained = false;
+
+ *did_some_progress = __perform_reclaim(gfp_mask, order, zonelist,
+ nodemask);
if (unlikely(!(*did_some_progress)))
return NULL;
@@ -5031,14 +5043,7 @@
calculate_totalreserve_pages();
}
-/**
- * setup_per_zone_wmarks - called when min_free_kbytes changes
- * or when memory is hot-{added|removed}
- *
- * Ensures that the watermark[min,low,high] values for each zone are set
- * correctly with respect to min_free_kbytes.
- */
-void setup_per_zone_wmarks(void)
+static void __setup_per_zone_wmarks(void)
{
unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
unsigned long lowmem_pages = 0;
@@ -5093,6 +5098,20 @@
calculate_totalreserve_pages();
}
+/**
+ * setup_per_zone_wmarks - called when min_free_kbytes changes
+ * or when memory is hot-{added|removed}
+ *
+ * Ensures that the watermark[min,low,high] values for each zone are set
+ * correctly with respect to min_free_kbytes.
+ */
+void setup_per_zone_wmarks(void)
+{
+ mutex_lock(&zonelists_mutex);
+ __setup_per_zone_wmarks();
+ mutex_unlock(&zonelists_mutex);
+}
+
/*
* The inactive anon list should be small enough that the VM never has to
* do too much work, but large enough that each inactive page has a chance
@@ -5593,7 +5612,7 @@
return ret;
}
-void unset_migratetype_isolate(struct page *page)
+void unset_migratetype_isolate(struct page *page, unsigned migratetype)
{
struct zone *zone;
unsigned long flags;
@@ -5601,8 +5620,8 @@
spin_lock_irqsave(&zone->lock, flags);
if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
goto out;
- set_pageblock_migratetype(page, MIGRATE_MOVABLE);
- move_freepages_block(zone, page, MIGRATE_MOVABLE);
+ set_pageblock_migratetype(page, migratetype);
+ move_freepages_block(zone, page, migratetype);
out:
spin_unlock_irqrestore(&zone->lock, flags);
}
@@ -5680,6 +5699,10 @@
* alloc_contig_range() -- tries to allocate given range of pages
* @start: start PFN to allocate
* @end: one-past-the-last PFN to allocate
+ * @migratetype: migratetype of the underlaying pageblocks (either
+ * #MIGRATE_MOVABLE or #MIGRATE_CMA). All pageblocks
+ * in range must have the same migratetype and it must
+ * be either of the two.
*
* The PFN range does not have to be pageblock or MAX_ORDER_NR_PAGES
* aligned, however it's the caller's responsibility to guarantee that
@@ -5692,7 +5715,8 @@
* pages which PFN is in [start, end) are allocated for the caller and
* need to be freed with free_contig_range().
*/
-int alloc_contig_range(unsigned long start, unsigned long end)
+int alloc_contig_range(unsigned long start, unsigned long end,
+ unsigned migratetype)
{
struct zone *zone = page_zone(pfn_to_page(start));
unsigned long outer_start, outer_end;
@@ -5723,7 +5747,7 @@
*/
ret = start_isolate_page_range(pfn_max_align_down(start),
- pfn_max_align_up(end));
+ pfn_max_align_up(end), migratetype);
if (ret)
goto done;
@@ -5783,7 +5807,7 @@
done:
undo_isolate_page_range(pfn_max_align_down(start),
- pfn_max_align_up(end));
+ pfn_max_align_up(end), migratetype);
return ret;
}
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index 4ae42bb..c9f0477 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -24,6 +24,7 @@
* to be MIGRATE_ISOLATE.
* @start_pfn: The lower PFN of the range to be isolated.
* @end_pfn: The upper PFN of the range to be isolated.
+ * @migratetype: migrate type to set in error recovery.
*
* Making page-allocation-type to be MIGRATE_ISOLATE means free pages in
* the range will never be allocated. Any free pages and pages freed in the
@@ -32,8 +33,8 @@
* start_pfn/end_pfn must be aligned to pageblock_order.
* Returns 0 on success and -EBUSY if any part of range cannot be isolated.
*/
-int
-start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
+int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
+ unsigned migratetype)
{
unsigned long pfn;
unsigned long undo_pfn;
@@ -56,7 +57,7 @@
for (pfn = start_pfn;
pfn < undo_pfn;
pfn += pageblock_nr_pages)
- unset_migratetype_isolate(pfn_to_page(pfn));
+ unset_migratetype_isolate(pfn_to_page(pfn), migratetype);
return -EBUSY;
}
@@ -64,8 +65,8 @@
/*
* Make isolated pages available again.
*/
-int
-undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
+int undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
+ unsigned migratetype)
{
unsigned long pfn;
struct page *page;
@@ -77,7 +78,7 @@
page = __first_valid_page(pfn, pageblock_nr_pages);
if (!page || get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
continue;
- unset_migratetype_isolate(page);
+ unset_migratetype_isolate(page, migratetype);
}
return 0;
}
@@ -86,7 +87,7 @@
* all pages in [start_pfn...end_pfn) must be in the same zone.
* zone->lock must be held before call this.
*
- * Returns 1 if all pages in the range is isolated.
+ * Returns 1 if all pages in the range are isolated.
*/
static int
__test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index fd3fe6a..65cee5d 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -469,7 +469,10 @@
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_soc_dai_digital_mute(codec_dai, 1);
- if (cpu_dai->driver->ops->shutdown) {
+ if (cpu_dai->driver->ops->shutdown)
+ cpu_dai->driver->ops->shutdown(substream, cpu_dai);
+
+ if (codec_dai->driver->ops->shutdown) {
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
codec_dai->driver->ops->shutdown(substream, codec_dai);
} else {
@@ -479,9 +482,6 @@
}
}
- if (codec_dai->driver->ops->shutdown)
- codec_dai->driver->ops->shutdown(substream, codec_dai);
-
if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
rtd->dai_link->ops->shutdown(substream);