aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-12-16 18:33:38 -0500
committerDavid S. Miller <davem@davemloft.net>2015-12-16 18:33:38 -0500
commit4d4f37910b8a120e9cf5a436256db84295437ac7 (patch)
treea197af9b3f0eaaee43b8e268640178ae9d41a350 /net
parent79aa05a24f01bcb0cfbac3deea4f12d9b4f64ba9 (diff)
parentcf1e05c63642ce65821a6277adfc2157f7334c9d (diff)
Merge tag 'mac80211-for-davem-2015-12-15' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says: ==================== Another set of fixes: * memory leak fixes (from Ola) * operating mode notification spec compliance fix (from Eyal) * copy rfkill names in case pointer becomes invalid (myself) * two hardware restart fixes (myself) * get rid of "limiting TX power" log spam (myself) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c3
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/mlme.c17
-rw-r--r--net/mac80211/rx.c3
-rw-r--r--net/mac80211/util.c113
-rw-r--r--net/mac80211/vht.c10
-rw-r--r--net/rfkill/core.c6
-rw-r--r--net/wireless/nl80211.c5
-rw-r--r--net/wireless/reg.c5
9 files changed, 92 insertions, 74 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index da471eef07bb..c12f348138ac 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1169,8 +1169,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1169 * rc isn't initialized here yet, so ignore it 1169 * rc isn't initialized here yet, so ignore it
1170 */ 1170 */
1171 __ieee80211_vht_handle_opmode(sdata, sta, 1171 __ieee80211_vht_handle_opmode(sdata, sta,
1172 params->opmode_notif, 1172 params->opmode_notif, band);
1173 band, false);
1174 } 1173 }
1175 1174
1176 if (ieee80211_vif_is_mesh(&sdata->vif)) 1175 if (ieee80211_vif_is_mesh(&sdata->vif))
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d832bd59236b..5322b4c71630 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1709,10 +1709,10 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
1709void ieee80211_sta_set_rx_nss(struct sta_info *sta); 1709void ieee80211_sta_set_rx_nss(struct sta_info *sta);
1710u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, 1710u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
1711 struct sta_info *sta, u8 opmode, 1711 struct sta_info *sta, u8 opmode,
1712 enum ieee80211_band band, bool nss_only); 1712 enum ieee80211_band band);
1713void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, 1713void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
1714 struct sta_info *sta, u8 opmode, 1714 struct sta_info *sta, u8 opmode,
1715 enum ieee80211_band band, bool nss_only); 1715 enum ieee80211_band band);
1716void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata, 1716void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
1717 struct ieee80211_sta_vht_cap *vht_cap); 1717 struct ieee80211_sta_vht_cap *vht_cap);
1718void ieee80211_get_vht_mask_from_cap(__le16 vht_cap, 1718void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b140cc6651f4..3aa04344942b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1379,21 +1379,26 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
1379 */ 1379 */
1380 if (has_80211h_pwr && 1380 if (has_80211h_pwr &&
1381 (!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) { 1381 (!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) {
1382 new_ap_level = pwr_level_80211h;
1383
1384 if (sdata->ap_power_level == new_ap_level)
1385 return 0;
1386
1382 sdata_dbg(sdata, 1387 sdata_dbg(sdata,
1383 "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", 1388 "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
1384 pwr_level_80211h, chan_pwr, pwr_reduction_80211h, 1389 pwr_level_80211h, chan_pwr, pwr_reduction_80211h,
1385 sdata->u.mgd.bssid); 1390 sdata->u.mgd.bssid);
1386 new_ap_level = pwr_level_80211h;
1387 } else { /* has_cisco_pwr is always true here. */ 1391 } else { /* has_cisco_pwr is always true here. */
1392 new_ap_level = pwr_level_cisco;
1393
1394 if (sdata->ap_power_level == new_ap_level)
1395 return 0;
1396
1388 sdata_dbg(sdata, 1397 sdata_dbg(sdata,
1389 "Limiting TX power to %d dBm as advertised by %pM\n", 1398 "Limiting TX power to %d dBm as advertised by %pM\n",
1390 pwr_level_cisco, sdata->u.mgd.bssid); 1399 pwr_level_cisco, sdata->u.mgd.bssid);
1391 new_ap_level = pwr_level_cisco;
1392 } 1400 }
1393 1401
1394 if (sdata->ap_power_level == new_ap_level)
1395 return 0;
1396
1397 sdata->ap_power_level = new_ap_level; 1402 sdata->ap_power_level = new_ap_level;
1398 if (__ieee80211_recalc_txpower(sdata)) 1403 if (__ieee80211_recalc_txpower(sdata))
1399 return BSS_CHANGED_TXPOWER; 1404 return BSS_CHANGED_TXPOWER;
@@ -3575,7 +3580,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3575 3580
3576 if (sta && elems.opmode_notif) 3581 if (sta && elems.opmode_notif)
3577 ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif, 3582 ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif,
3578 rx_status->band, true); 3583 rx_status->band);
3579 mutex_unlock(&local->sta_mtx); 3584 mutex_unlock(&local->sta_mtx);
3580 3585
3581 changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt, 3586 changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8bae5de0dc44..82af407fea7a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2736,8 +2736,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2736 opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode; 2736 opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
2737 2737
2738 ieee80211_vht_handle_opmode(rx->sdata, rx->sta, 2738 ieee80211_vht_handle_opmode(rx->sdata, rx->sta,
2739 opmode, status->band, 2739 opmode, status->band);
2740 false);
2741 goto handled; 2740 goto handled;
2742 } 2741 }
2743 default: 2742 default:
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 74058020b7d6..33344f5a66a8 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1641,6 +1641,29 @@ void ieee80211_stop_device(struct ieee80211_local *local)
1641 drv_stop(local); 1641 drv_stop(local);
1642} 1642}
1643 1643
1644static void ieee80211_flush_completed_scan(struct ieee80211_local *local,
1645 bool aborted)
1646{
1647 /* It's possible that we don't handle the scan completion in
1648 * time during suspend, so if it's still marked as completed
1649 * here, queue the work and flush it to clean things up.
1650 * Instead of calling the worker function directly here, we
1651 * really queue it to avoid potential races with other flows
1652 * scheduling the same work.
1653 */
1654 if (test_bit(SCAN_COMPLETED, &local->scanning)) {
1655 /* If coming from reconfiguration failure, abort the scan so
1656 * we don't attempt to continue a partial HW scan - which is
1657 * possible otherwise if (e.g.) the 2.4 GHz portion was the
1658 * completed scan, and a 5 GHz portion is still pending.
1659 */
1660 if (aborted)
1661 set_bit(SCAN_ABORTED, &local->scanning);
1662 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
1663 flush_delayed_work(&local->scan_work);
1664 }
1665}
1666
1644static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local) 1667static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
1645{ 1668{
1646 struct ieee80211_sub_if_data *sdata; 1669 struct ieee80211_sub_if_data *sdata;
@@ -1660,6 +1683,8 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
1660 local->suspended = false; 1683 local->suspended = false;
1661 local->in_reconfig = false; 1684 local->in_reconfig = false;
1662 1685
1686 ieee80211_flush_completed_scan(local, true);
1687
1663 /* scheduled scan clearly can't be running any more, but tell 1688 /* scheduled scan clearly can't be running any more, but tell
1664 * cfg80211 and clear local state 1689 * cfg80211 and clear local state
1665 */ 1690 */
@@ -1698,6 +1723,27 @@ static void ieee80211_assign_chanctx(struct ieee80211_local *local,
1698 mutex_unlock(&local->chanctx_mtx); 1723 mutex_unlock(&local->chanctx_mtx);
1699} 1724}
1700 1725
1726static void ieee80211_reconfig_stations(struct ieee80211_sub_if_data *sdata)
1727{
1728 struct ieee80211_local *local = sdata->local;
1729 struct sta_info *sta;
1730
1731 /* add STAs back */
1732 mutex_lock(&local->sta_mtx);
1733 list_for_each_entry(sta, &local->sta_list, list) {
1734 enum ieee80211_sta_state state;
1735
1736 if (!sta->uploaded || sta->sdata != sdata)
1737 continue;
1738
1739 for (state = IEEE80211_STA_NOTEXIST;
1740 state < sta->sta_state; state++)
1741 WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
1742 state + 1));
1743 }
1744 mutex_unlock(&local->sta_mtx);
1745}
1746
1701int ieee80211_reconfig(struct ieee80211_local *local) 1747int ieee80211_reconfig(struct ieee80211_local *local)
1702{ 1748{
1703 struct ieee80211_hw *hw = &local->hw; 1749 struct ieee80211_hw *hw = &local->hw;
@@ -1833,50 +1879,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1833 WARN_ON(drv_add_chanctx(local, ctx)); 1879 WARN_ON(drv_add_chanctx(local, ctx));
1834 mutex_unlock(&local->chanctx_mtx); 1880 mutex_unlock(&local->chanctx_mtx);
1835 1881
1836 list_for_each_entry(sdata, &local->interfaces, list) {
1837 if (!ieee80211_sdata_running(sdata))
1838 continue;
1839 ieee80211_assign_chanctx(local, sdata);
1840 }
1841
1842 sdata = rtnl_dereference(local->monitor_sdata); 1882 sdata = rtnl_dereference(local->monitor_sdata);
1843 if (sdata && ieee80211_sdata_running(sdata)) 1883 if (sdata && ieee80211_sdata_running(sdata))
1844 ieee80211_assign_chanctx(local, sdata); 1884 ieee80211_assign_chanctx(local, sdata);
1845 } 1885 }
1846 1886
1847 /* add STAs back */
1848 mutex_lock(&local->sta_mtx);
1849 list_for_each_entry(sta, &local->sta_list, list) {
1850 enum ieee80211_sta_state state;
1851
1852 if (!sta->uploaded)
1853 continue;
1854
1855 /* AP-mode stations will be added later */
1856 if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
1857 continue;
1858
1859 for (state = IEEE80211_STA_NOTEXIST;
1860 state < sta->sta_state; state++)
1861 WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
1862 state + 1));
1863 }
1864 mutex_unlock(&local->sta_mtx);
1865
1866 /* reconfigure tx conf */
1867 if (hw->queues >= IEEE80211_NUM_ACS) {
1868 list_for_each_entry(sdata, &local->interfaces, list) {
1869 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
1870 sdata->vif.type == NL80211_IFTYPE_MONITOR ||
1871 !ieee80211_sdata_running(sdata))
1872 continue;
1873
1874 for (i = 0; i < IEEE80211_NUM_ACS; i++)
1875 drv_conf_tx(local, sdata, i,
1876 &sdata->tx_conf[i]);
1877 }
1878 }
1879
1880 /* reconfigure hardware */ 1887 /* reconfigure hardware */
1881 ieee80211_hw_config(local, ~0); 1888 ieee80211_hw_config(local, ~0);
1882 1889
@@ -1889,6 +1896,22 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1889 if (!ieee80211_sdata_running(sdata)) 1896 if (!ieee80211_sdata_running(sdata))
1890 continue; 1897 continue;
1891 1898
1899 ieee80211_assign_chanctx(local, sdata);
1900
1901 switch (sdata->vif.type) {
1902 case NL80211_IFTYPE_AP_VLAN:
1903 case NL80211_IFTYPE_MONITOR:
1904 break;
1905 default:
1906 ieee80211_reconfig_stations(sdata);
1907 /* fall through */
1908 case NL80211_IFTYPE_AP: /* AP stations are handled later */
1909 for (i = 0; i < IEEE80211_NUM_ACS; i++)
1910 drv_conf_tx(local, sdata, i,
1911 &sdata->tx_conf[i]);
1912 break;
1913 }
1914
1892 /* common change flags for all interface types */ 1915 /* common change flags for all interface types */
1893 changed = BSS_CHANGED_ERP_CTS_PROT | 1916 changed = BSS_CHANGED_ERP_CTS_PROT |
1894 BSS_CHANGED_ERP_PREAMBLE | 1917 BSS_CHANGED_ERP_PREAMBLE |
@@ -2074,17 +2097,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
2074 mb(); 2097 mb();
2075 local->resuming = false; 2098 local->resuming = false;
2076 2099
2077 /* It's possible that we don't handle the scan completion in 2100 ieee80211_flush_completed_scan(local, false);
2078 * time during suspend, so if it's still marked as completed
2079 * here, queue the work and flush it to clean things up.
2080 * Instead of calling the worker function directly here, we
2081 * really queue it to avoid potential races with other flows
2082 * scheduling the same work.
2083 */
2084 if (test_bit(SCAN_COMPLETED, &local->scanning)) {
2085 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
2086 flush_delayed_work(&local->scan_work);
2087 }
2088 2101
2089 if (local->open_count && !reconfig_due_to_wowlan) 2102 if (local->open_count && !reconfig_due_to_wowlan)
2090 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); 2103 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index ff1c798921a6..c38b2f07a919 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -378,7 +378,7 @@ void ieee80211_sta_set_rx_nss(struct sta_info *sta)
378 378
379u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, 379u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
380 struct sta_info *sta, u8 opmode, 380 struct sta_info *sta, u8 opmode,
381 enum ieee80211_band band, bool nss_only) 381 enum ieee80211_band band)
382{ 382{
383 struct ieee80211_local *local = sdata->local; 383 struct ieee80211_local *local = sdata->local;
384 struct ieee80211_supported_band *sband; 384 struct ieee80211_supported_band *sband;
@@ -401,9 +401,6 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
401 changed |= IEEE80211_RC_NSS_CHANGED; 401 changed |= IEEE80211_RC_NSS_CHANGED;
402 } 402 }
403 403
404 if (nss_only)
405 return changed;
406
407 switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) { 404 switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
408 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ: 405 case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ:
409 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20; 406 sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20;
@@ -430,13 +427,12 @@ u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
430 427
431void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, 428void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
432 struct sta_info *sta, u8 opmode, 429 struct sta_info *sta, u8 opmode,
433 enum ieee80211_band band, bool nss_only) 430 enum ieee80211_band band)
434{ 431{
435 struct ieee80211_local *local = sdata->local; 432 struct ieee80211_local *local = sdata->local;
436 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 433 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
437 434
438 u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, 435 u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, band);
439 band, nss_only);
440 436
441 if (changed > 0) 437 if (changed > 0)
442 rate_control_rate_update(local, sband, sta, changed); 438 rate_control_rate_update(local, sband, sta, changed);
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index b41e9ea2ffff..f53bf3b6558b 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -49,7 +49,6 @@
49struct rfkill { 49struct rfkill {
50 spinlock_t lock; 50 spinlock_t lock;
51 51
52 const char *name;
53 enum rfkill_type type; 52 enum rfkill_type type;
54 53
55 unsigned long state; 54 unsigned long state;
@@ -73,6 +72,7 @@ struct rfkill {
73 struct delayed_work poll_work; 72 struct delayed_work poll_work;
74 struct work_struct uevent_work; 73 struct work_struct uevent_work;
75 struct work_struct sync_work; 74 struct work_struct sync_work;
75 char name[];
76}; 76};
77#define to_rfkill(d) container_of(d, struct rfkill, dev) 77#define to_rfkill(d) container_of(d, struct rfkill, dev)
78 78
@@ -876,14 +876,14 @@ struct rfkill * __must_check rfkill_alloc(const char *name,
876 if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES)) 876 if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))
877 return NULL; 877 return NULL;
878 878
879 rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL); 879 rfkill = kzalloc(sizeof(*rfkill) + strlen(name) + 1, GFP_KERNEL);
880 if (!rfkill) 880 if (!rfkill)
881 return NULL; 881 return NULL;
882 882
883 spin_lock_init(&rfkill->lock); 883 spin_lock_init(&rfkill->lock);
884 INIT_LIST_HEAD(&rfkill->node); 884 INIT_LIST_HEAD(&rfkill->node);
885 rfkill->type = type; 885 rfkill->type = type;
886 rfkill->name = name; 886 strcpy(rfkill->name, name);
887 rfkill->ops = ops; 887 rfkill->ops = ops;
888 rfkill->data = ops_data; 888 rfkill->data = ops_data;
889 889
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c71e274c810a..75b0d23ee882 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7941,8 +7941,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
7941 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) { 7941 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
7942 if (!(rdev->wiphy.features & 7942 if (!(rdev->wiphy.features &
7943 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) || 7943 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) ||
7944 !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) 7944 !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) {
7945 kzfree(connkeys);
7945 return -EINVAL; 7946 return -EINVAL;
7947 }
7946 connect.flags |= ASSOC_REQ_USE_RRM; 7948 connect.flags |= ASSOC_REQ_USE_RRM;
7947 } 7949 }
7948 7950
@@ -9503,6 +9505,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
9503 if (new_triggers.tcp && new_triggers.tcp->sock) 9505 if (new_triggers.tcp && new_triggers.tcp->sock)
9504 sock_release(new_triggers.tcp->sock); 9506 sock_release(new_triggers.tcp->sock);
9505 kfree(new_triggers.tcp); 9507 kfree(new_triggers.tcp);
9508 kfree(new_triggers.nd_config);
9506 return err; 9509 return err;
9507} 9510}
9508#endif 9511#endif
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2e8d6f39ed56..06d050da0d94 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3029,6 +3029,7 @@ int set_regdom(const struct ieee80211_regdomain *rd,
3029 break; 3029 break;
3030 default: 3030 default:
3031 WARN(1, "invalid initiator %d\n", lr->initiator); 3031 WARN(1, "invalid initiator %d\n", lr->initiator);
3032 kfree(rd);
3032 return -EINVAL; 3033 return -EINVAL;
3033 } 3034 }
3034 3035
@@ -3221,8 +3222,10 @@ int __init regulatory_init(void)
3221 /* We always try to get an update for the static regdomain */ 3222 /* We always try to get an update for the static regdomain */
3222 err = regulatory_hint_core(cfg80211_world_regdom->alpha2); 3223 err = regulatory_hint_core(cfg80211_world_regdom->alpha2);
3223 if (err) { 3224 if (err) {
3224 if (err == -ENOMEM) 3225 if (err == -ENOMEM) {
3226 platform_device_unregister(reg_pdev);
3225 return err; 3227 return err;
3228 }
3226 /* 3229 /*
3227 * N.B. kobject_uevent_env() can fail mainly for when we're out 3230 * N.B. kobject_uevent_env() can fail mainly for when we're out
3228 * memory which is handled and propagated appropriately above 3231 * memory which is handled and propagated appropriately above