drop patches merged in 3.17
This commit is contained in:
parent
a18b584961
commit
c30210e69f
@ -1,57 +0,0 @@
|
|||||||
From 1c3d95edf026c6fb446f53913c61ff1036c469cd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Frederic Danis <frederic.danis@linux.intel.com>
|
|
||||||
Date: Mon, 2 Jun 2014 21:19:46 +0300
|
|
||||||
Subject: [PATCH 1/8] ath6kl: Fix ath6kl_bmi_read_hi32 macro
|
|
||||||
|
|
||||||
tmp may be used uninitialized if ath6kl_bmi_read() returns an error.
|
|
||||||
|
|
||||||
Signed-off-by: Frederic Danis <frederic.danis@linux.intel.com>
|
|
||||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
|
||||||
---
|
|
||||||
drivers/net/wireless/ath/ath6kl/bmi.h | 3 ++-
|
|
||||||
drivers/net/wireless/ath/ath6kl/init.c | 12 ++++++++++--
|
|
||||||
2 files changed, 12 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h
|
|
||||||
index 18fdd69..397a52f 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/bmi.h
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/bmi.h
|
|
||||||
@@ -242,7 +242,8 @@ struct ath6kl_bmi_target_info {
|
|
||||||
(void) (check_type == val); \
|
|
||||||
addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \
|
|
||||||
ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \
|
|
||||||
- *val = le32_to_cpu(tmp); \
|
|
||||||
+ if (!ret) \
|
|
||||||
+ *val = le32_to_cpu(tmp); \
|
|
||||||
ret; \
|
|
||||||
})
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
index d5ef211..6e1e699 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
@@ -1161,11 +1161,19 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
|
||||||
ath6kl_bmi_write_hi32(ar, hi_board_data,
|
|
||||||
board_address);
|
|
||||||
} else {
|
|
||||||
- ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
|
|
||||||
+ ret = ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
|
|
||||||
+ if (ret) {
|
|
||||||
+ ath6kl_err("Failed to get board file target address.\n");
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* determine where in target ram to write extended board data */
|
|
||||||
- ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
|
|
||||||
+ ret = ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
|
|
||||||
+ if (ret) {
|
|
||||||
+ ath6kl_err("Failed to get extended board file target address.\n");
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (ar->target_type == TARGET_TYPE_AR6003 &&
|
|
||||||
board_ext_address == 0) {
|
|
||||||
--
|
|
||||||
2.1.0
|
|
||||||
|
|
@ -1,202 +0,0 @@
|
|||||||
From eba95bceb4c9f537c6c8a5aeba4277e76599e269 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kalle Valo <kvalo@qca.qualcomm.com>
|
|
||||||
Date: Tue, 17 Jun 2014 12:40:52 +0300
|
|
||||||
Subject: [PATCH 2/8] ath6kl: convert ar6004 hardware flags to firmware feature
|
|
||||||
flags
|
|
||||||
|
|
||||||
The functionality defined through these flags were actually firmware features
|
|
||||||
which can change between firmware versions. To make it possible to support
|
|
||||||
different firmware versions with the same driver, convert the flags to firmware
|
|
||||||
feature flags.
|
|
||||||
|
|
||||||
For backwards compatibility support for old ar6004 firmware FW
|
|
||||||
API 3 or smaller images we forcefully set the feature bits in the driver.
|
|
||||||
Starting from FW API 5 the firmware image needs to set them.
|
|
||||||
|
|
||||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
|
||||||
---
|
|
||||||
drivers/net/wireless/ath/ath6kl/cfg80211.c | 6 ++++--
|
|
||||||
drivers/net/wireless/ath/ath6kl/core.c | 16 ++++++++++++++++
|
|
||||||
drivers/net/wireless/ath/ath6kl/core.h | 12 +++++++++---
|
|
||||||
drivers/net/wireless/ath/ath6kl/init.c | 16 +++++++---------
|
|
||||||
drivers/net/wireless/ath/ath6kl/usb.c | 6 ++++--
|
|
||||||
drivers/net/wireless/ath/ath6kl/wmi.c | 3 ++-
|
|
||||||
6 files changed, 42 insertions(+), 17 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
|
|
||||||
index 0e26f4a..d139f2a 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
|
|
||||||
@@ -2899,7 +2899,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|
||||||
if (info->inactivity_timeout) {
|
|
||||||
inactivity_timeout = info->inactivity_timeout;
|
|
||||||
|
|
||||||
- if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
|
|
||||||
+ if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
|
||||||
+ ar->fw_capabilities))
|
|
||||||
inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
|
|
||||||
60);
|
|
||||||
|
|
||||||
@@ -3782,7 +3783,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
|
||||||
ath6kl_band_5ghz.ht_cap.ht_supported = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
|
|
||||||
+ if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
|
||||||
+ ar->fw_capabilities)) {
|
|
||||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
|
||||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
|
||||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
|
|
||||||
index b0b6520..0df74b2 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/core.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/core.c
|
|
||||||
@@ -123,6 +123,22 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
|
|
||||||
|
|
||||||
/* FIXME: we should free all firmwares in the error cases below */
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Backwards compatibility support for older ar6004 firmware images
|
|
||||||
+ * which do not set these feature flags.
|
|
||||||
+ */
|
|
||||||
+ if (ar->target_type == TARGET_TYPE_AR6004 &&
|
|
||||||
+ ar->fw_api <= 4) {
|
|
||||||
+ __set_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
|
||||||
+ ar->fw_capabilities);
|
|
||||||
+ __set_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
|
||||||
+ ar->fw_capabilities);
|
|
||||||
+
|
|
||||||
+ if (ar->hw.id == AR6004_HW_1_3_VERSION)
|
|
||||||
+ __set_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
|
||||||
+ ar->fw_capabilities);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Indicate that WMI is enabled (although not ready yet) */
|
|
||||||
set_bit(WMI_ENABLED, &ar->flag);
|
|
||||||
ar->wmi = ath6kl_wmi_init(ar);
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
index 26b0f92..bd91c44 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
@@ -136,6 +136,15 @@ enum ath6kl_fw_capability {
|
|
||||||
*/
|
|
||||||
ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
|
|
||||||
|
|
||||||
+ /* WMI_SET_TX_SELECT_RATES_CMDID uses 64 bit size rate table */
|
|
||||||
+ ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
|
||||||
+
|
|
||||||
+ /* WMI_AP_CONN_INACT_CMDID uses minutes as units */
|
|
||||||
+ ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
|
|
||||||
+
|
|
||||||
+ /* use low priority endpoint for all data */
|
|
||||||
+ ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
|
||||||
+
|
|
||||||
/* this needs to be last */
|
|
||||||
ATH6KL_FW_CAPABILITY_MAX,
|
|
||||||
};
|
|
||||||
@@ -149,9 +158,6 @@ struct ath6kl_fw_ie {
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ath6kl_hw_flags {
|
|
||||||
- ATH6KL_HW_64BIT_RATES = BIT(0),
|
|
||||||
- ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1),
|
|
||||||
- ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2),
|
|
||||||
ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3),
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
index 6e1e699..ed086ea 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
@@ -93,8 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
|
|
||||||
.board_addr = 0x433900,
|
|
||||||
.refclk_hz = 26000000,
|
|
||||||
.uarttx_pin = 11,
|
|
||||||
- .flags = ATH6KL_HW_64BIT_RATES |
|
|
||||||
- ATH6KL_HW_AP_INACTIVITY_MINS,
|
|
||||||
+ .flags = 0,
|
|
||||||
|
|
||||||
.fw = {
|
|
||||||
.dir = AR6004_HW_1_0_FW_DIR,
|
|
||||||
@@ -114,8 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
|
|
||||||
.board_addr = 0x43d400,
|
|
||||||
.refclk_hz = 40000000,
|
|
||||||
.uarttx_pin = 11,
|
|
||||||
- .flags = ATH6KL_HW_64BIT_RATES |
|
|
||||||
- ATH6KL_HW_AP_INACTIVITY_MINS,
|
|
||||||
+ .flags = 0,
|
|
||||||
.fw = {
|
|
||||||
.dir = AR6004_HW_1_1_FW_DIR,
|
|
||||||
.fw = AR6004_HW_1_1_FIRMWARE_FILE,
|
|
||||||
@@ -134,8 +132,7 @@ static const struct ath6kl_hw hw_list[] = {
|
|
||||||
.board_addr = 0x435c00,
|
|
||||||
.refclk_hz = 40000000,
|
|
||||||
.uarttx_pin = 11,
|
|
||||||
- .flags = ATH6KL_HW_64BIT_RATES |
|
|
||||||
- ATH6KL_HW_AP_INACTIVITY_MINS,
|
|
||||||
+ .flags = 0,
|
|
||||||
|
|
||||||
.fw = {
|
|
||||||
.dir = AR6004_HW_1_2_FW_DIR,
|
|
||||||
@@ -154,9 +151,7 @@ static const struct ath6kl_hw hw_list[] = {
|
|
||||||
.board_addr = 0x436400,
|
|
||||||
.refclk_hz = 40000000,
|
|
||||||
.uarttx_pin = 11,
|
|
||||||
- .flags = ATH6KL_HW_64BIT_RATES |
|
|
||||||
- ATH6KL_HW_AP_INACTIVITY_MINS |
|
|
||||||
- ATH6KL_HW_MAP_LP_ENDPOINT,
|
|
||||||
+ .flags = 0,
|
|
||||||
|
|
||||||
.fw = {
|
|
||||||
.dir = AR6004_HW_1_3_FW_DIR,
|
|
||||||
@@ -1575,6 +1570,9 @@ static const struct fw_capa_str_map {
|
|
||||||
{ ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
|
|
||||||
{ ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
|
|
||||||
{ ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
|
|
||||||
+ { ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
|
|
||||||
+ { ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
|
|
||||||
+ { ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
|
|
||||||
index 3afc5a4..e5a9e7f 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/usb.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
|
|
||||||
@@ -802,7 +802,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
|
|
||||||
break;
|
|
||||||
case WMI_DATA_VI_SVC:
|
|
||||||
|
|
||||||
- if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
|
|
||||||
+ if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
|
||||||
+ ar->fw_capabilities))
|
|
||||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
|
|
||||||
else
|
|
||||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
|
|
||||||
@@ -814,7 +815,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
|
|
||||||
break;
|
|
||||||
case WMI_DATA_VO_SVC:
|
|
||||||
|
|
||||||
- if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
|
|
||||||
+ if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
|
||||||
+ ar->fw_capabilities))
|
|
||||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
|
|
||||||
else
|
|
||||||
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
|
|
||||||
index 4d7f9e4..6ecc0a4 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
|
|
||||||
@@ -2838,7 +2838,8 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
|
|
||||||
{
|
|
||||||
struct ath6kl *ar = wmi->parent_dev;
|
|
||||||
|
|
||||||
- if (ar->hw.flags & ATH6KL_HW_64BIT_RATES)
|
|
||||||
+ if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
|
|
||||||
+ ar->fw_capabilities))
|
|
||||||
return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
|
|
||||||
else
|
|
||||||
return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
|
|
||||||
--
|
|
||||||
2.1.0
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
From b056397e98a9d7fb8fed9f5c837461f3dd8b0132 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jessica Wu <kvalo@qca.qualcomm.com>
|
|
||||||
Date: Tue, 17 Jun 2014 12:40:58 +0300
|
|
||||||
Subject: [PATCH 3/8] ath6kl: implement rx flush for htc pipe
|
|
||||||
|
|
||||||
rx flush was not implemented for htc pipe, add that now. Doesn't fix any known
|
|
||||||
issues.
|
|
||||||
|
|
||||||
Also free the skb if htc control messages get canceled.
|
|
||||||
|
|
||||||
Signed-off-by: Jessica Wu <wjessica@qca.qualcomm.com>
|
|
||||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
|
||||||
---
|
|
||||||
drivers/net/wireless/ath/ath6kl/htc_pipe.c | 32 +++++++++++++++++++++++++++---
|
|
||||||
1 file changed, 29 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
|
|
||||||
index 756fe52..ca1a18c 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
|
|
||||||
@@ -1170,8 +1170,12 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
|
|
||||||
static void htc_rxctrl_complete(struct htc_target *context,
|
|
||||||
struct htc_packet *packet)
|
|
||||||
{
|
|
||||||
- /* TODO, can't really receive HTC control messages yet.... */
|
|
||||||
- ath6kl_dbg(ATH6KL_DBG_HTC, "%s: invalid call function\n", __func__);
|
|
||||||
+ struct sk_buff *skb = packet->skb;
|
|
||||||
+
|
|
||||||
+ if (packet->endpoint == ENDPOINT_0 &&
|
|
||||||
+ packet->status == -ECANCELED &&
|
|
||||||
+ skb != NULL)
|
|
||||||
+ dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* htc pipe initialization */
|
|
||||||
@@ -1678,7 +1682,29 @@ static void ath6kl_htc_pipe_activity_changed(struct htc_target *target,
|
|
||||||
|
|
||||||
static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target)
|
|
||||||
{
|
|
||||||
- /* TODO */
|
|
||||||
+ struct htc_endpoint *endpoint;
|
|
||||||
+ struct htc_packet *packet, *tmp_pkt;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
|
|
||||||
+ endpoint = &target->endpoint[i];
|
|
||||||
+
|
|
||||||
+ spin_lock_bh(&target->rx_lock);
|
|
||||||
+
|
|
||||||
+ list_for_each_entry_safe(packet, tmp_pkt,
|
|
||||||
+ &endpoint->rx_bufq, list) {
|
|
||||||
+ list_del(&packet->list);
|
|
||||||
+ spin_unlock_bh(&target->rx_lock);
|
|
||||||
+ ath6kl_dbg(ATH6KL_DBG_HTC,
|
|
||||||
+ "htc rx flush pkt 0x%p len %d ep %d\n",
|
|
||||||
+ packet, packet->buf_len,
|
|
||||||
+ packet->endpoint);
|
|
||||||
+ dev_kfree_skb(packet->pkt_cntxt);
|
|
||||||
+ spin_lock_bh(&target->rx_lock);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ spin_unlock_bh(&target->rx_lock);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ath6kl_htc_pipe_credit_setup(struct htc_target *target,
|
|
||||||
--
|
|
||||||
2.1.0
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
|||||||
From 958e1be848c92006ee4b95190d3725daf3a70034 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kalle Valo <kvalo@qca.qualcomm.com>
|
|
||||||
Date: Tue, 17 Jun 2014 12:41:04 +0300
|
|
||||||
Subject: [PATCH 4/8] ath6kl: don't set hi_refclk_hz if hardware version
|
|
||||||
doesn't need it
|
|
||||||
|
|
||||||
Needed for ar6004 hw3.0 support.
|
|
||||||
|
|
||||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
|
||||||
---
|
|
||||||
drivers/net/wireless/ath/ath6kl/init.c | 9 ++++++---
|
|
||||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
index ed086ea..a0400a1 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
@@ -624,9 +624,12 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
/* Configure target refclk_hz */
|
|
||||||
- status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz);
|
|
||||||
- if (status)
|
|
||||||
- return status;
|
|
||||||
+ if (ar->hw.refclk_hz != 0) {
|
|
||||||
+ status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz,
|
|
||||||
+ ar->hw.refclk_hz);
|
|
||||||
+ if (status)
|
|
||||||
+ return status;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.1.0
|
|
||||||
|
|
@ -1,193 +0,0 @@
|
|||||||
From c1d32d3038ff4d366b837cedb95aeb1801730f2c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jessica Wu <wjessica@qca.qualcomm.com>
|
|
||||||
Date: Tue, 17 Jun 2014 12:41:10 +0300
|
|
||||||
Subject: [PATCH 5/8] ath6kl: add support wmi rate tables with mcs15
|
|
||||||
|
|
||||||
Some of the firmware versions support rate tables up to mcs15, add support for
|
|
||||||
that.
|
|
||||||
|
|
||||||
Signed-off-by: Jessica Wu <wjessica@qca.qualcomm.com>
|
|
||||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
|
||||||
---
|
|
||||||
drivers/net/wireless/ath/ath6kl/core.h | 3 ++
|
|
||||||
drivers/net/wireless/ath/ath6kl/init.c | 1 +
|
|
||||||
drivers/net/wireless/ath/ath6kl/main.c | 11 ++++--
|
|
||||||
drivers/net/wireless/ath/ath6kl/wmi.c | 69 ++++++++++++++++++++++++++++++++--
|
|
||||||
drivers/net/wireless/ath/ath6kl/wmi.h | 2 +-
|
|
||||||
5 files changed, 77 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
index bd91c44..23a7763 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
@@ -145,6 +145,9 @@ enum ath6kl_fw_capability {
|
|
||||||
/* use low priority endpoint for all data */
|
|
||||||
ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
|
|
||||||
|
|
||||||
+ /* ratetable is the 2 stream version (max MCS15) */
|
|
||||||
+ ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
|
|
||||||
+
|
|
||||||
/* this needs to be last */
|
|
||||||
ATH6KL_FW_CAPABILITY_MAX,
|
|
||||||
};
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
index a0400a1..8cd0cdf 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
@@ -1576,6 +1576,7 @@ static const struct fw_capa_str_map {
|
|
||||||
{ ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
|
|
||||||
{ ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
|
|
||||||
{ ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
|
|
||||||
+ { ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
|
|
||||||
index d565546..baa447f 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/main.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/main.c
|
|
||||||
@@ -702,6 +702,7 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
|
||||||
struct ath6kl *ar = vif->ar;
|
|
||||||
struct target_stats *stats = &vif->target_stats;
|
|
||||||
struct tkip_ccmp_stats *ccmp_stats;
|
|
||||||
+ s32 rate;
|
|
||||||
u8 ac;
|
|
||||||
|
|
||||||
if (len < sizeof(*tgt_stats))
|
|
||||||
@@ -731,8 +732,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
|
||||||
le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
|
|
||||||
stats->tx_rts_fail_cnt +=
|
|
||||||
le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
|
|
||||||
- stats->tx_ucast_rate =
|
|
||||||
- ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
|
|
||||||
+
|
|
||||||
+ rate = a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate);
|
|
||||||
+ stats->tx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
|
|
||||||
|
|
||||||
stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
|
|
||||||
stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
|
|
||||||
@@ -749,8 +751,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
|
||||||
le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
|
|
||||||
stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
|
|
||||||
stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
|
|
||||||
- stats->rx_ucast_rate =
|
|
||||||
- ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
|
|
||||||
+
|
|
||||||
+ rate = a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate);
|
|
||||||
+ stats->rx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
|
|
||||||
|
|
||||||
ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
|
|
||||||
index 6ecc0a4..94df345 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
|
|
||||||
@@ -59,6 +59,55 @@ static const s32 wmi_rate_tbl[][2] = {
|
|
||||||
{0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const s32 wmi_rate_tbl_mcs15[][2] = {
|
|
||||||
+ /* {W/O SGI, with SGI} */
|
|
||||||
+ {1000, 1000},
|
|
||||||
+ {2000, 2000},
|
|
||||||
+ {5500, 5500},
|
|
||||||
+ {11000, 11000},
|
|
||||||
+ {6000, 6000},
|
|
||||||
+ {9000, 9000},
|
|
||||||
+ {12000, 12000},
|
|
||||||
+ {18000, 18000},
|
|
||||||
+ {24000, 24000},
|
|
||||||
+ {36000, 36000},
|
|
||||||
+ {48000, 48000},
|
|
||||||
+ {54000, 54000},
|
|
||||||
+ {6500, 7200}, /* HT 20, MCS 0 */
|
|
||||||
+ {13000, 14400},
|
|
||||||
+ {19500, 21700},
|
|
||||||
+ {26000, 28900},
|
|
||||||
+ {39000, 43300},
|
|
||||||
+ {52000, 57800},
|
|
||||||
+ {58500, 65000},
|
|
||||||
+ {65000, 72200},
|
|
||||||
+ {13000, 14400}, /* HT 20, MCS 8 */
|
|
||||||
+ {26000, 28900},
|
|
||||||
+ {39000, 43300},
|
|
||||||
+ {52000, 57800},
|
|
||||||
+ {78000, 86700},
|
|
||||||
+ {104000, 115600},
|
|
||||||
+ {117000, 130000},
|
|
||||||
+ {130000, 144400}, /* HT 20, MCS 15 */
|
|
||||||
+ {13500, 15000}, /*HT 40, MCS 0 */
|
|
||||||
+ {27000, 30000},
|
|
||||||
+ {40500, 45000},
|
|
||||||
+ {54000, 60000},
|
|
||||||
+ {81000, 90000},
|
|
||||||
+ {108000, 120000},
|
|
||||||
+ {121500, 135000},
|
|
||||||
+ {135000, 150000},
|
|
||||||
+ {27000, 30000}, /*HT 40, MCS 8 */
|
|
||||||
+ {54000, 60000},
|
|
||||||
+ {81000, 90000},
|
|
||||||
+ {108000, 120000},
|
|
||||||
+ {162000, 180000},
|
|
||||||
+ {216000, 240000},
|
|
||||||
+ {243000, 270000},
|
|
||||||
+ {270000, 300000}, /*HT 40, MCS 15 */
|
|
||||||
+ {0, 0}
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
|
|
||||||
static const u8 up_to_ac[] = {
|
|
||||||
WMM_AC_BE,
|
|
||||||
@@ -3280,9 +3329,11 @@ int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2)
|
|
||||||
NO_SYNC_WMIFLAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
-s32 ath6kl_wmi_get_rate(s8 rate_index)
|
|
||||||
+s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index)
|
|
||||||
{
|
|
||||||
+ struct ath6kl *ar = wmi->parent_dev;
|
|
||||||
u8 sgi = 0;
|
|
||||||
+ s32 ret;
|
|
||||||
|
|
||||||
if (rate_index == RATE_AUTO)
|
|
||||||
return 0;
|
|
||||||
@@ -3293,10 +3344,20 @@ s32 ath6kl_wmi_get_rate(s8 rate_index)
|
|
||||||
sgi = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (WARN_ON(rate_index > RATE_MCS_7_40))
|
|
||||||
- rate_index = RATE_MCS_7_40;
|
|
||||||
+ if (test_bit(ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
|
|
||||||
+ ar->fw_capabilities)) {
|
|
||||||
+ if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl_mcs15)))
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ ret = wmi_rate_tbl_mcs15[(u32) rate_index][sgi];
|
|
||||||
+ } else {
|
|
||||||
+ if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl)))
|
|
||||||
+ return 0;
|
|
||||||
|
|
||||||
- return wmi_rate_tbl[(u32) rate_index][sgi];
|
|
||||||
+ ret = wmi_rate_tbl[(u32) rate_index][sgi];
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
|
|
||||||
index 7809afb..8d4d885 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
|
|
||||||
@@ -2632,7 +2632,7 @@ int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
|
|
||||||
struct ath6kl_htcap *htcap);
|
|
||||||
int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
|
|
||||||
|
|
||||||
-s32 ath6kl_wmi_get_rate(s8 rate_index);
|
|
||||||
+s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index);
|
|
||||||
|
|
||||||
int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
|
|
||||||
__be32 ips0, __be32 ips1);
|
|
||||||
--
|
|
||||||
2.1.0
|
|
||||||
|
|
@ -1,211 +0,0 @@
|
|||||||
From 7880377012ef48bf75498648c3bcbcb60460ff28 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jessica Wu <wjessica@qca.qualcomm.com>
|
|
||||||
Date: Tue, 17 Jun 2014 12:41:16 +0300
|
|
||||||
Subject: [PATCH 6/8] ath6kl: add support for ar6004 hw3.0
|
|
||||||
|
|
||||||
This change enables ath6kl driver to support ar6004 hw3.0. At the same time do
|
|
||||||
some fixes in firmware initialisation which applies to ar6004 hw1.3 as well.
|
|
||||||
|
|
||||||
Signed-off-by: Jessica Wu <wjessica@qca.qualcomm.com>
|
|
||||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
|
||||||
---
|
|
||||||
drivers/net/wireless/ath/ath6kl/core.h | 21 ++++++++++++--
|
|
||||||
drivers/net/wireless/ath/ath6kl/init.c | 52 +++++++++++++++++++++++++++++++---
|
|
||||||
drivers/net/wireless/ath/ath6kl/main.c | 6 +++-
|
|
||||||
drivers/net/wireless/ath/ath6kl/usb.c | 1 +
|
|
||||||
4 files changed, 73 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
index 23a7763..2b78c86 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/core.h
|
|
||||||
@@ -148,6 +148,9 @@ enum ath6kl_fw_capability {
|
|
||||||
/* ratetable is the 2 stream version (max MCS15) */
|
|
||||||
ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
|
|
||||||
|
|
||||||
+ /* firmare doesn't support IP checksumming */
|
|
||||||
+ ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
|
|
||||||
+
|
|
||||||
/* this needs to be last */
|
|
||||||
ATH6KL_FW_CAPABILITY_MAX,
|
|
||||||
};
|
|
||||||
@@ -167,6 +170,7 @@ enum ath6kl_hw_flags {
|
|
||||||
#define ATH6KL_FW_API2_FILE "fw-2.bin"
|
|
||||||
#define ATH6KL_FW_API3_FILE "fw-3.bin"
|
|
||||||
#define ATH6KL_FW_API4_FILE "fw-4.bin"
|
|
||||||
+#define ATH6KL_FW_API5_FILE "fw-5.bin"
|
|
||||||
|
|
||||||
/* AR6003 1.0 definitions */
|
|
||||||
#define AR6003_HW_1_0_VERSION 0x300002ba
|
|
||||||
@@ -224,8 +228,21 @@ enum ath6kl_hw_flags {
|
|
||||||
#define AR6004_HW_1_3_VERSION 0x31c8088a
|
|
||||||
#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3"
|
|
||||||
#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin"
|
|
||||||
-#define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
|
|
||||||
-#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
|
|
||||||
+#define AR6004_HW_1_3_TCMD_FIRMWARE_FILE "utf.bin"
|
|
||||||
+#define AR6004_HW_1_3_UTF_FIRMWARE_FILE "utf.bin"
|
|
||||||
+#define AR6004_HW_1_3_TESTSCRIPT_FILE "nullTestFlow.bin"
|
|
||||||
+#define AR6004_HW_1_3_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
|
|
||||||
+#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
|
|
||||||
+
|
|
||||||
+/* AR6004 3.0 definitions */
|
|
||||||
+#define AR6004_HW_3_0_VERSION 0x31C809F8
|
|
||||||
+#define AR6004_HW_3_0_FW_DIR "ath6k/AR6004/hw3.0"
|
|
||||||
+#define AR6004_HW_3_0_FIRMWARE_FILE "fw.ram.bin"
|
|
||||||
+#define AR6004_HW_3_0_TCMD_FIRMWARE_FILE "utf.bin"
|
|
||||||
+#define AR6004_HW_3_0_UTF_FIRMWARE_FILE "utf.bin"
|
|
||||||
+#define AR6004_HW_3_0_TESTSCRIPT_FILE "nullTestFlow.bin"
|
|
||||||
+#define AR6004_HW_3_0_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
|
|
||||||
+#define AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
|
|
||||||
|
|
||||||
/* Per STA data, used in AP mode */
|
|
||||||
#define STA_PS_AWAKE BIT(0)
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
index 8cd0cdf..a6111848 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/init.c
|
|
||||||
@@ -149,18 +149,43 @@ static const struct ath6kl_hw hw_list[] = {
|
|
||||||
.board_ext_data_addr = 0x437000,
|
|
||||||
.reserved_ram_size = 7168,
|
|
||||||
.board_addr = 0x436400,
|
|
||||||
- .refclk_hz = 40000000,
|
|
||||||
+ .refclk_hz = 0,
|
|
||||||
.uarttx_pin = 11,
|
|
||||||
.flags = 0,
|
|
||||||
|
|
||||||
.fw = {
|
|
||||||
.dir = AR6004_HW_1_3_FW_DIR,
|
|
||||||
.fw = AR6004_HW_1_3_FIRMWARE_FILE,
|
|
||||||
+ .tcmd = AR6004_HW_1_3_TCMD_FIRMWARE_FILE,
|
|
||||||
+ .utf = AR6004_HW_1_3_UTF_FIRMWARE_FILE,
|
|
||||||
+ .testscript = AR6004_HW_1_3_TESTSCRIPT_FILE,
|
|
||||||
},
|
|
||||||
|
|
||||||
.fw_board = AR6004_HW_1_3_BOARD_DATA_FILE,
|
|
||||||
.fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
|
|
||||||
},
|
|
||||||
+ {
|
|
||||||
+ .id = AR6004_HW_3_0_VERSION,
|
|
||||||
+ .name = "ar6004 hw 3.0",
|
|
||||||
+ .dataset_patch_addr = 0,
|
|
||||||
+ .app_load_addr = 0x1234,
|
|
||||||
+ .board_ext_data_addr = 0,
|
|
||||||
+ .reserved_ram_size = 7168,
|
|
||||||
+ .board_addr = 0x436400,
|
|
||||||
+ .testscript_addr = 0,
|
|
||||||
+ .flags = 0,
|
|
||||||
+
|
|
||||||
+ .fw = {
|
|
||||||
+ .dir = AR6004_HW_3_0_FW_DIR,
|
|
||||||
+ .fw = AR6004_HW_3_0_FIRMWARE_FILE,
|
|
||||||
+ .tcmd = AR6004_HW_3_0_TCMD_FIRMWARE_FILE,
|
|
||||||
+ .utf = AR6004_HW_3_0_UTF_FIRMWARE_FILE,
|
|
||||||
+ .testscript = AR6004_HW_3_0_TESTSCRIPT_FILE,
|
|
||||||
+ },
|
|
||||||
+
|
|
||||||
+ .fw_board = AR6004_HW_3_0_BOARD_DATA_FILE,
|
|
||||||
+ .fw_default_board = AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE,
|
|
||||||
+ },
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -596,7 +621,9 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
|
||||||
* but possible in theory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
- if (ar->target_type == TARGET_TYPE_AR6003) {
|
|
||||||
+ if ((ar->target_type == TARGET_TYPE_AR6003) ||
|
|
||||||
+ (ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
|
|
||||||
+ (ar->version.target_ver == AR6004_HW_3_0_VERSION)) {
|
|
||||||
param = ar->hw.board_ext_data_addr;
|
|
||||||
ram_reserved_size = ar->hw.reserved_ram_size;
|
|
||||||
|
|
||||||
@@ -1110,6 +1137,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
+ ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API5_FILE);
|
|
||||||
+ if (ret == 0) {
|
|
||||||
+ ar->fw_api = 5;
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
|
|
||||||
if (ret == 0) {
|
|
||||||
ar->fw_api = 4;
|
|
||||||
@@ -1236,7 +1269,13 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* record the fact that Board Data IS initialized */
|
|
||||||
- ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1);
|
|
||||||
+ if ((ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
|
|
||||||
+ (ar->version.target_ver == AR6004_HW_3_0_VERSION))
|
|
||||||
+ param = board_data_size;
|
|
||||||
+ else
|
|
||||||
+ param = 1;
|
|
||||||
+
|
|
||||||
+ ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, param);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1367,7 +1406,11 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
|
|
||||||
}
|
|
||||||
|
|
||||||
ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
|
|
||||||
- ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
|
|
||||||
+
|
|
||||||
+ if ((ar->version.target_ver != AR6004_HW_1_3_VERSION) &&
|
|
||||||
+ (ar->version.target_ver != AR6004_HW_3_0_VERSION))
|
|
||||||
+ ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
|
|
||||||
+
|
|
||||||
ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
@@ -1577,6 +1620,7 @@ static const struct fw_capa_str_map {
|
|
||||||
{ ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
|
|
||||||
{ ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
|
|
||||||
{ ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
|
|
||||||
+ { ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
|
|
||||||
index baa447f..21516bc 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/main.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/main.c
|
|
||||||
@@ -1293,6 +1293,8 @@ static const struct net_device_ops ath6kl_netdev_ops = {
|
|
||||||
|
|
||||||
void init_netdev(struct net_device *dev)
|
|
||||||
{
|
|
||||||
+ struct ath6kl *ar = ath6kl_priv(dev);
|
|
||||||
+
|
|
||||||
dev->netdev_ops = &ath6kl_netdev_ops;
|
|
||||||
dev->destructor = free_netdev;
|
|
||||||
dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
|
|
||||||
@@ -1304,7 +1306,9 @@ void init_netdev(struct net_device *dev)
|
|
||||||
WMI_MAX_TX_META_SZ +
|
|
||||||
ATH6KL_HTC_ALIGN_BYTES, 4);
|
|
||||||
|
|
||||||
- dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
|
||||||
+ if (!test_bit(ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
|
|
||||||
+ ar->fw_capabilities))
|
|
||||||
+ dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
|
|
||||||
index e5a9e7f..c443258 100644
|
|
||||||
--- a/drivers/net/wireless/ath/ath6kl/usb.c
|
|
||||||
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
|
|
||||||
@@ -1210,6 +1210,7 @@ static int ath6kl_usb_pm_reset_resume(struct usb_interface *intf)
|
|
||||||
|
|
||||||
/* table of devices that work with this driver */
|
|
||||||
static struct usb_device_id ath6kl_usb_ids[] = {
|
|
||||||
+ {USB_DEVICE(0x0cf3, 0x9375)},
|
|
||||||
{USB_DEVICE(0x0cf3, 0x9374)},
|
|
||||||
{ /* Terminating entry */ },
|
|
||||||
};
|
|
||||||
--
|
|
||||||
2.1.0
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
From 9b11eb44eff7ede6bc3a94511cf9dfda75af9c9f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jarkko Nikula <jarkko.nikula@linux.intel.com>
|
|
||||||
Date: Wed, 6 Aug 2014 09:48:14 +0300
|
|
||||||
Subject: [PATCH] ASoC: Intel: Update Baytrail ADSP firmware name
|
|
||||||
|
|
||||||
Update the initial Baytrail ADSP firmware file name with the one that is now
|
|
||||||
in linux-firmware.git. Please see linux-firmware.git commit 7551a3a78453
|
|
||||||
("fw_sst_0f28: Add firmware for Intel Baytrail SST DSP").
|
|
||||||
|
|
||||||
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
|
|
||||||
Signed-off-by: Mark Brown <broonie@linaro.org>
|
|
||||||
---
|
|
||||||
sound/soc/intel/sst-acpi.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/sst-acpi.c
|
|
||||||
index 42edc6f..03d0a16 100644
|
|
||||||
--- a/sound/soc/intel/sst-acpi.c
|
|
||||||
+++ b/sound/soc/intel/sst-acpi.c
|
|
||||||
@@ -246,8 +246,8 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = {
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sst_acpi_mach baytrail_machines[] = {
|
|
||||||
- { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-i2s_master" },
|
|
||||||
- { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-i2s_master" },
|
|
||||||
+ { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master" },
|
|
||||||
+ { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master" },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
@ -1,461 +0,0 @@
|
|||||||
From patchwork Tue May 20 12:59:23 2014
|
|
||||||
Content-Type: text/plain; charset="utf-8"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
Subject: [V3,4/5] I2C/ACPI: Add i2c ACPI operation region support
|
|
||||||
From: "lan,Tianyu" <tianyu.lan@intel.com>
|
|
||||||
X-Patchwork-Id: 4209471
|
|
||||||
Message-Id: <1400590764-11108-5-git-send-email-tianyu.lan@intel.com>
|
|
||||||
To: wsa@the-dreams.de, rjw@rjwysocki.net,
|
|
||||||
mika.westerberg@linux.intel.com, awilliam@redhat.com, lenb@kernel.org
|
|
||||||
Cc: Lan Tianyu <tianyu.lan@intel.com>, linux-i2c@vger.kernel.org,
|
|
||||||
linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org
|
|
||||||
Date: Tue, 20 May 2014 20:59:23 +0800
|
|
||||||
|
|
||||||
ACPI 5.0 spec(5.5.2.4.5) defines GenericSerialBus(i2c, spi, uart) operation region.
|
|
||||||
It allows ACPI aml code able to access such kind of devices to implement
|
|
||||||
some ACPI standard method.
|
|
||||||
|
|
||||||
ACPI Spec defines some access attribute to associate with i2c protocol.
|
|
||||||
AttribQuick Read/Write Quick Protocol
|
|
||||||
AttribSendReceive Send/Receive Byte Protocol
|
|
||||||
AttribByte Read/Write Byte Protocol
|
|
||||||
AttribWord Read/Write Word Protocol
|
|
||||||
AttribBlock Read/Write Block Protocol
|
|
||||||
AttribBytes Read/Write N-Bytes Protocol
|
|
||||||
AttribProcessCall Process Call Protocol
|
|
||||||
AttribBlockProcessCall Write Block-Read Block Process Call Protocol
|
|
||||||
AttribRawBytes Raw Read/Write N-BytesProtocol
|
|
||||||
AttribRawProcessBytes Raw Process Call Protocol
|
|
||||||
|
|
||||||
On the Asus T100TA, Bios use GenericSerialBus operation region to access
|
|
||||||
i2c device to get battery info.
|
|
||||||
|
|
||||||
Sample code From Asus T100TA
|
|
||||||
|
|
||||||
Scope (_SB.I2C1)
|
|
||||||
{
|
|
||||||
Name (UMPC, ResourceTemplate ()
|
|
||||||
{
|
|
||||||
I2cSerialBus (0x0066, ControllerInitiated, 0x00061A80,
|
|
||||||
AddressingMode7Bit, "\\_SB.I2C1",
|
|
||||||
0x00, ResourceConsumer, ,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
OperationRegion (DVUM, GenericSerialBus, Zero, 0x0100)
|
|
||||||
Field (DVUM, BufferAcc, NoLock, Preserve)
|
|
||||||
{
|
|
||||||
Connection (UMPC),
|
|
||||||
Offset (0x81),
|
|
||||||
AccessAs (BufferAcc, AttribBytes (0x3E)),
|
|
||||||
FGC0, 8
|
|
||||||
}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
Device (BATC)
|
|
||||||
{
|
|
||||||
Name (_HID, EisaId ("PNP0C0A")) // _HID: Hardware ID
|
|
||||||
Name (_UID, One) // _UID: Unique ID
|
|
||||||
...
|
|
||||||
|
|
||||||
Method (_BST, 0, NotSerialized) // _BST: Battery Status
|
|
||||||
{
|
|
||||||
If (LEqual (AVBL, One))
|
|
||||||
{
|
|
||||||
Store (FGC0, BFFG)
|
|
||||||
If (LNotEqual (STAT, One))
|
|
||||||
{
|
|
||||||
ShiftRight (CHST, 0x04, Local0)
|
|
||||||
And (Local0, 0x03, Local0)
|
|
||||||
If (LOr (LEqual (Local0, One), LEqual (Local0, 0x02)))
|
|
||||||
{
|
|
||||||
Store (0x02, Local1)
|
|
||||||
}
|
|
||||||
...
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
The i2c operation region is defined under I2C1 scope. _BST method under
|
|
||||||
battery device BATC read battery status from the field "FCG0". The request
|
|
||||||
would be sent to i2c operation region handler.
|
|
||||||
|
|
||||||
This patch is to add i2c ACPI operation region support. Due to there are
|
|
||||||
only "Byte" and "Bytes" protocol access on the Asus T100TA, other protocols
|
|
||||||
have not been tested.
|
|
||||||
|
|
||||||
About RawBytes and RawProcessBytes protocol, they needs specific drivers to interpret
|
|
||||||
reference data from AML code according ACPI 5.0 SPEC(5.5.2.4.5.3.9 and 5.5.2.4.5.3.10).
|
|
||||||
So far, not found such case and will add when find real case.
|
|
||||||
|
|
||||||
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
|
|
||||||
|
|
||||||
---
|
|
||||||
drivers/i2c/Makefile | 5 +-
|
|
||||||
drivers/i2c/i2c-acpi.c | 273 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
drivers/i2c/i2c-core.c | 2 +
|
|
||||||
include/linux/acpi.h | 11 ++
|
|
||||||
include/linux/i2c.h | 10 ++
|
|
||||||
5 files changed, 300 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100644 drivers/i2c/i2c-acpi.c
|
|
||||||
|
|
||||||
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
|
|
||||||
index 1722f50..80db307 100644
|
|
||||||
--- a/drivers/i2c/Makefile
|
|
||||||
+++ b/drivers/i2c/Makefile
|
|
||||||
@@ -2,8 +2,11 @@
|
|
||||||
# Makefile for the i2c core.
|
|
||||||
#
|
|
||||||
|
|
||||||
+i2ccore-y := i2c-core.o
|
|
||||||
+i2ccore-$(CONFIG_ACPI) += i2c-acpi.o
|
|
||||||
+
|
|
||||||
obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o
|
|
||||||
-obj-$(CONFIG_I2C) += i2c-core.o
|
|
||||||
+obj-$(CONFIG_I2C) += i2ccore.o
|
|
||||||
obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o
|
|
||||||
obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
|
|
||||||
obj-$(CONFIG_I2C_MUX) += i2c-mux.o
|
|
||||||
diff --git a/drivers/i2c/i2c-acpi.c b/drivers/i2c/i2c-acpi.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..f7f4c89
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/drivers/i2c/i2c-acpi.c
|
|
||||||
@@ -0,0 +1,273 @@
|
|
||||||
+/*
|
|
||||||
+ * I2C ACPI code
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2014 Intel Corp
|
|
||||||
+ *
|
|
||||||
+ * Author: Lan Tianyu <tianyu.lan@intel.com>
|
|
||||||
+ *
|
|
||||||
+ * This program is free software; you can redistribute it and/or modify
|
|
||||||
+ * it under the terms of the GNU General Public License version 2 as
|
|
||||||
+ * published by the Free Software Foundation.
|
|
||||||
+ *
|
|
||||||
+ * This program is distributed in the hope that it will be useful, but
|
|
||||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
+ * for more details.
|
|
||||||
+ */
|
|
||||||
+#define pr_fmt(fmt) "I2C/ACPI : " fmt
|
|
||||||
+
|
|
||||||
+#include <linux/kernel.h>
|
|
||||||
+#include <linux/errno.h>
|
|
||||||
+#include <linux/err.h>
|
|
||||||
+#include <linux/i2c.h>
|
|
||||||
+#include <linux/acpi.h>
|
|
||||||
+
|
|
||||||
+struct acpi_i2c_handler_data {
|
|
||||||
+ struct acpi_connection_info info;
|
|
||||||
+ struct i2c_adapter *adapter;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+struct gsb_buffer {
|
|
||||||
+ u8 status;
|
|
||||||
+ u8 len;
|
|
||||||
+ union {
|
|
||||||
+ u16 wdata;
|
|
||||||
+ u8 bdata;
|
|
||||||
+ u8 data[0];
|
|
||||||
+ };
|
|
||||||
+} __packed;
|
|
||||||
+
|
|
||||||
+static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
|
|
||||||
+ u8 cmd, u8 *data, u8 data_len)
|
|
||||||
+{
|
|
||||||
+
|
|
||||||
+ struct i2c_msg msgs[2];
|
|
||||||
+ int ret;
|
|
||||||
+ u8 *buffer;
|
|
||||||
+
|
|
||||||
+ buffer = kzalloc(data_len, GFP_KERNEL);
|
|
||||||
+ if (!buffer)
|
|
||||||
+ return AE_NO_MEMORY;
|
|
||||||
+
|
|
||||||
+ msgs[0].addr = client->addr;
|
|
||||||
+ msgs[0].flags = client->flags;
|
|
||||||
+ msgs[0].len = 1;
|
|
||||||
+ msgs[0].buf = &cmd;
|
|
||||||
+
|
|
||||||
+ msgs[1].addr = client->addr;
|
|
||||||
+ msgs[1].flags = client->flags | I2C_M_RD;
|
|
||||||
+ msgs[1].len = data_len;
|
|
||||||
+ msgs[1].buf = buffer;
|
|
||||||
+
|
|
||||||
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ dev_err(&client->adapter->dev, "i2c read failed\n");
|
|
||||||
+ else
|
|
||||||
+ memcpy(data, buffer, data_len);
|
|
||||||
+
|
|
||||||
+ kfree(buffer);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int acpi_gsb_i2c_write_bytes(struct i2c_client *client,
|
|
||||||
+ u8 cmd, u8 *data, u8 data_len)
|
|
||||||
+{
|
|
||||||
+
|
|
||||||
+ struct i2c_msg msgs[1];
|
|
||||||
+ u8 *buffer;
|
|
||||||
+ int ret = AE_OK;
|
|
||||||
+
|
|
||||||
+ buffer = kzalloc(data_len + 1, GFP_KERNEL);
|
|
||||||
+ if (!buffer)
|
|
||||||
+ return AE_NO_MEMORY;
|
|
||||||
+
|
|
||||||
+ buffer[0] = cmd;
|
|
||||||
+ memcpy(buffer + 1, data, data_len);
|
|
||||||
+
|
|
||||||
+ msgs[0].addr = client->addr;
|
|
||||||
+ msgs[0].flags = client->flags;
|
|
||||||
+ msgs[0].len = data_len + 1;
|
|
||||||
+ msgs[0].buf = buffer;
|
|
||||||
+
|
|
||||||
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ dev_err(&client->adapter->dev, "i2c write failed\n");
|
|
||||||
+
|
|
||||||
+ kfree(buffer);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static acpi_status
|
|
||||||
+acpi_i2c_space_handler(u32 function, acpi_physical_address command,
|
|
||||||
+ u32 bits, u64 *value64,
|
|
||||||
+ void *handler_context, void *region_context)
|
|
||||||
+{
|
|
||||||
+ struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
|
|
||||||
+ struct acpi_i2c_handler_data *data = handler_context;
|
|
||||||
+ struct acpi_connection_info *info = &data->info;
|
|
||||||
+ struct acpi_resource_i2c_serialbus *sb;
|
|
||||||
+ struct i2c_adapter *adapter = data->adapter;
|
|
||||||
+ struct i2c_client client;
|
|
||||||
+ struct acpi_resource *ares;
|
|
||||||
+ u32 accessor_type = function >> 16;
|
|
||||||
+ u8 action = function & ACPI_IO_MASK;
|
|
||||||
+ acpi_status ret = AE_OK;
|
|
||||||
+ int status;
|
|
||||||
+
|
|
||||||
+ ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
|
|
||||||
+ if (ACPI_FAILURE(ret))
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) {
|
|
||||||
+ ret = AE_BAD_PARAMETER;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ sb = &ares->data.i2c_serial_bus;
|
|
||||||
+ if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) {
|
|
||||||
+ ret = AE_BAD_PARAMETER;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ memset(&client, 0, sizeof(client));
|
|
||||||
+ client.adapter = adapter;
|
|
||||||
+ client.addr = sb->slave_address;
|
|
||||||
+ client.flags = 0;
|
|
||||||
+
|
|
||||||
+ if (sb->access_mode == ACPI_I2C_10BIT_MODE)
|
|
||||||
+ client.flags |= I2C_CLIENT_TEN;
|
|
||||||
+
|
|
||||||
+ switch (accessor_type) {
|
|
||||||
+ case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV:
|
|
||||||
+ if (action == ACPI_READ) {
|
|
||||||
+ status = i2c_smbus_read_byte(&client);
|
|
||||||
+ if (status >= 0) {
|
|
||||||
+ gsb->bdata = status;
|
|
||||||
+ status = 0;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ status = i2c_smbus_write_byte(&client, gsb->bdata);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case ACPI_GSB_ACCESS_ATTRIB_BYTE:
|
|
||||||
+ if (action == ACPI_READ) {
|
|
||||||
+ status = i2c_smbus_read_byte_data(&client, command);
|
|
||||||
+ if (status >= 0) {
|
|
||||||
+ gsb->bdata = status;
|
|
||||||
+ status = 0;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ status = i2c_smbus_write_byte_data(&client, command,
|
|
||||||
+ gsb->bdata);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case ACPI_GSB_ACCESS_ATTRIB_WORD:
|
|
||||||
+ if (action == ACPI_READ) {
|
|
||||||
+ status = i2c_smbus_read_word_data(&client, command);
|
|
||||||
+ if (status >= 0) {
|
|
||||||
+ gsb->wdata = status;
|
|
||||||
+ status = 0;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ status = i2c_smbus_write_word_data(&client, command,
|
|
||||||
+ gsb->wdata);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case ACPI_GSB_ACCESS_ATTRIB_BLOCK:
|
|
||||||
+ if (action == ACPI_READ) {
|
|
||||||
+ status = i2c_smbus_read_block_data(&client, command,
|
|
||||||
+ gsb->data);
|
|
||||||
+ if (status >= 0) {
|
|
||||||
+ gsb->len = status;
|
|
||||||
+ status = 0;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ status = i2c_smbus_write_block_data(&client, command,
|
|
||||||
+ gsb->len, gsb->data);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE:
|
|
||||||
+ if (action == ACPI_READ) {
|
|
||||||
+ status = acpi_gsb_i2c_read_bytes(&client, command,
|
|
||||||
+ gsb->data, info->access_length);
|
|
||||||
+ if (status > 0)
|
|
||||||
+ status = 0;
|
|
||||||
+ } else {
|
|
||||||
+ status = acpi_gsb_i2c_write_bytes(&client, command,
|
|
||||||
+ gsb->data, info->access_length);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ pr_info("protocol(0x%02x) is not supported.\n", accessor_type);
|
|
||||||
+ ret = AE_BAD_PARAMETER;
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ gsb->status = status;
|
|
||||||
+
|
|
||||||
+ err:
|
|
||||||
+ ACPI_FREE(ares);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
|
|
||||||
+{
|
|
||||||
+ acpi_handle handle = ACPI_HANDLE(adapter->dev.parent);
|
|
||||||
+ struct acpi_i2c_handler_data *data;
|
|
||||||
+ acpi_status status;
|
|
||||||
+
|
|
||||||
+ if (!handle)
|
|
||||||
+ return -ENODEV;
|
|
||||||
+
|
|
||||||
+ data = kzalloc(sizeof(struct acpi_i2c_handler_data),
|
|
||||||
+ GFP_KERNEL);
|
|
||||||
+ if (!data)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ data->adapter = adapter;
|
|
||||||
+ status = acpi_bus_attach_private_data(handle, (void *)data);
|
|
||||||
+ if (ACPI_FAILURE(status)) {
|
|
||||||
+ kfree(data);
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ status = acpi_install_address_space_handler(handle,
|
|
||||||
+ ACPI_ADR_SPACE_GSBUS,
|
|
||||||
+ &acpi_i2c_space_handler,
|
|
||||||
+ NULL,
|
|
||||||
+ data);
|
|
||||||
+ if (ACPI_FAILURE(status)) {
|
|
||||||
+ dev_err(&adapter->dev, "Error installing i2c space handler\n");
|
|
||||||
+ acpi_bus_detach_private_data(handle);
|
|
||||||
+ kfree(data);
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
|
|
||||||
+{
|
|
||||||
+ acpi_handle handle = ACPI_HANDLE(adapter->dev.parent);
|
|
||||||
+ struct acpi_i2c_handler_data *data;
|
|
||||||
+ acpi_status status;
|
|
||||||
+
|
|
||||||
+ if (!handle)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ acpi_remove_address_space_handler(handle,
|
|
||||||
+ ACPI_ADR_SPACE_GSBUS,
|
|
||||||
+ &acpi_i2c_space_handler);
|
|
||||||
+
|
|
||||||
+ status = acpi_bus_get_private_data(handle, (void **)&data);
|
|
||||||
+ if (ACPI_SUCCESS(status))
|
|
||||||
+ kfree(data);
|
|
||||||
+
|
|
||||||
+ acpi_bus_detach_private_data(handle);
|
|
||||||
+}
|
|
||||||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
|
|
||||||
index 7c7f4b8..e25cb84 100644
|
|
||||||
--- a/drivers/i2c/i2c-core.c
|
|
||||||
+++ b/drivers/i2c/i2c-core.c
|
|
||||||
@@ -1293,6 +1293,7 @@ exit_recovery:
|
|
||||||
/* create pre-declared device nodes */
|
|
||||||
of_i2c_register_devices(adap);
|
|
||||||
acpi_i2c_register_devices(adap);
|
|
||||||
+ acpi_i2c_install_space_handler(adap);
|
|
||||||
|
|
||||||
if (adap->nr < __i2c_first_dynamic_bus_num)
|
|
||||||
i2c_scan_static_board_info(adap);
|
|
||||||
@@ -1466,6 +1467,7 @@ void i2c_del_adapter(struct i2c_adapter *adap)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ acpi_i2c_remove_space_handler(adap);
|
|
||||||
/* Tell drivers about this removal */
|
|
||||||
mutex_lock(&core_lock);
|
|
||||||
bus_for_each_drv(&i2c_bus_type, NULL, adap,
|
|
||||||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
|
|
||||||
index 7a8f2cd..ea53b9b 100644
|
|
||||||
--- a/include/linux/acpi.h
|
|
||||||
+++ b/include/linux/acpi.h
|
|
||||||
@@ -361,6 +361,17 @@ extern bool osc_sb_apei_support_acked;
|
|
||||||
#define OSC_PCI_EXPRESS_CAPABILITY_CONTROL 0x00000010
|
|
||||||
#define OSC_PCI_CONTROL_MASKS 0x0000001f
|
|
||||||
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_QUICK 0x00000002
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_SEND_RCV 0x00000004
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_BYTE 0x00000006
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_WORD 0x00000008
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_BLOCK 0x0000000A
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE 0x0000000B
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_WORD_CALL 0x0000000C
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_BLOCK_CALL 0x0000000D
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_RAW_BYTES 0x0000000E
|
|
||||||
+#define ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS 0x0000000F
|
|
||||||
+
|
|
||||||
extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
|
|
||||||
u32 *mask, u32 req);
|
|
||||||
|
|
||||||
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
|
|
||||||
index b556e0a..f7a939a 100644
|
|
||||||
--- a/include/linux/i2c.h
|
|
||||||
+++ b/include/linux/i2c.h
|
|
||||||
@@ -577,4 +577,14 @@ static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_OF */
|
|
||||||
|
|
||||||
+#ifdef CONFIG_ACPI
|
|
||||||
+int acpi_i2c_install_space_handler(struct i2c_adapter *adapter);
|
|
||||||
+void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter);
|
|
||||||
+#else
|
|
||||||
+static inline void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
|
|
||||||
+{ }
|
|
||||||
+static inline int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
|
|
||||||
+{ return 0; }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
#endif /* _LINUX_I2C_H */
|
|
@ -1,310 +0,0 @@
|
|||||||
From patchwork Tue May 20 12:59:24 2014
|
|
||||||
Content-Type: text/plain; charset="utf-8"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
Subject: [V3,
|
|
||||||
5/5] I2C/ACPI: Clean up I2C ACPI code and Add CONFIG_I2C_ACPI config
|
|
||||||
From: "lan,Tianyu" <tianyu.lan@intel.com>
|
|
||||||
X-Patchwork-Id: 4209461
|
|
||||||
Message-Id: <1400590764-11108-6-git-send-email-tianyu.lan@intel.com>
|
|
||||||
To: wsa@the-dreams.de, rjw@rjwysocki.net,
|
|
||||||
mika.westerberg@linux.intel.com, awilliam@redhat.com, lenb@kernel.org
|
|
||||||
Cc: Lan Tianyu <tianyu.lan@intel.com>, linux-i2c@vger.kernel.org,
|
|
||||||
linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org
|
|
||||||
Date: Tue, 20 May 2014 20:59:24 +0800
|
|
||||||
|
|
||||||
Clean up ACPI related code in the i2c core and add CONFIG_I2C_ACPI
|
|
||||||
to enable I2C ACPI code.
|
|
||||||
|
|
||||||
Current there is a race between removing I2C ACPI operation region
|
|
||||||
and ACPI AML code accessing. So make i2c core built-in if CONFIG_I2C_ACPI
|
|
||||||
is set.
|
|
||||||
|
|
||||||
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
|
|
||||||
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
|
|
||||||
|
|
||||||
---
|
|
||||||
drivers/i2c/Kconfig | 18 +++++++++-
|
|
||||||
drivers/i2c/Makefile | 2 +-
|
|
||||||
drivers/i2c/i2c-acpi.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
drivers/i2c/i2c-core.c | 95 --------------------------------------------------
|
|
||||||
include/linux/i2c.h | 4 ++-
|
|
||||||
5 files changed, 110 insertions(+), 98 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
|
|
||||||
index 7b7ea32..3e3b680 100644
|
|
||||||
--- a/drivers/i2c/Kconfig
|
|
||||||
+++ b/drivers/i2c/Kconfig
|
|
||||||
@@ -2,7 +2,9 @@
|
|
||||||
# I2C subsystem configuration
|
|
||||||
#
|
|
||||||
|
|
||||||
-menuconfig I2C
|
|
||||||
+menu "I2C support"
|
|
||||||
+
|
|
||||||
+config I2C
|
|
||||||
tristate "I2C support"
|
|
||||||
select RT_MUTEXES
|
|
||||||
---help---
|
|
||||||
@@ -21,6 +23,18 @@ menuconfig I2C
|
|
||||||
This I2C support can also be built as a module. If so, the module
|
|
||||||
will be called i2c-core.
|
|
||||||
|
|
||||||
+config I2C_ACPI
|
|
||||||
+ bool "I2C ACPI support"
|
|
||||||
+ select I2C
|
|
||||||
+ depends on ACPI
|
|
||||||
+ default y
|
|
||||||
+ help
|
|
||||||
+ Say Y here if you want to enable ACPI I2C support. This includes support
|
|
||||||
+ for automatic enumeration of I2C slave devices and support for ACPI I2C
|
|
||||||
+ Operation Regions. Operation Regions allow firmware (BIOS) code to
|
|
||||||
+ access I2C slave devices, such as smart batteries through an I2C host
|
|
||||||
+ controller driver.
|
|
||||||
+
|
|
||||||
if I2C
|
|
||||||
|
|
||||||
config I2C_BOARDINFO
|
|
||||||
@@ -124,3 +138,5 @@ config I2C_DEBUG_BUS
|
|
||||||
on.
|
|
||||||
|
|
||||||
endif # I2C
|
|
||||||
+
|
|
||||||
+endmenu
|
|
||||||
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
|
|
||||||
index 80db307..a1f590c 100644
|
|
||||||
--- a/drivers/i2c/Makefile
|
|
||||||
+++ b/drivers/i2c/Makefile
|
|
||||||
@@ -3,7 +3,7 @@
|
|
||||||
#
|
|
||||||
|
|
||||||
i2ccore-y := i2c-core.o
|
|
||||||
-i2ccore-$(CONFIG_ACPI) += i2c-acpi.o
|
|
||||||
+i2ccore-$(CONFIG_I2C_ACPI) += i2c-acpi.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o
|
|
||||||
obj-$(CONFIG_I2C) += i2ccore.o
|
|
||||||
diff --git a/drivers/i2c/i2c-acpi.c b/drivers/i2c/i2c-acpi.c
|
|
||||||
index f7f4c89..e8b6196 100644
|
|
||||||
--- a/drivers/i2c/i2c-acpi.c
|
|
||||||
+++ b/drivers/i2c/i2c-acpi.c
|
|
||||||
@@ -37,6 +37,95 @@ struct gsb_buffer {
|
|
||||||
};
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
+static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
|
|
||||||
+{
|
|
||||||
+ struct i2c_board_info *info = data;
|
|
||||||
+
|
|
||||||
+ if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
|
|
||||||
+ struct acpi_resource_i2c_serialbus *sb;
|
|
||||||
+
|
|
||||||
+ sb = &ares->data.i2c_serial_bus;
|
|
||||||
+ if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
|
|
||||||
+ info->addr = sb->slave_address;
|
|
||||||
+ if (sb->access_mode == ACPI_I2C_10BIT_MODE)
|
|
||||||
+ info->flags |= I2C_CLIENT_TEN;
|
|
||||||
+ }
|
|
||||||
+ } else if (info->irq < 0) {
|
|
||||||
+ struct resource r;
|
|
||||||
+
|
|
||||||
+ if (acpi_dev_resource_interrupt(ares, 0, &r))
|
|
||||||
+ info->irq = r.start;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Tell the ACPI core to skip this resource */
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
|
|
||||||
+ void *data, void **return_value)
|
|
||||||
+{
|
|
||||||
+ struct i2c_adapter *adapter = data;
|
|
||||||
+ struct list_head resource_list;
|
|
||||||
+ struct i2c_board_info info;
|
|
||||||
+ struct acpi_device *adev;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ if (acpi_bus_get_device(handle, &adev))
|
|
||||||
+ return AE_OK;
|
|
||||||
+ if (acpi_bus_get_status(adev) || !adev->status.present)
|
|
||||||
+ return AE_OK;
|
|
||||||
+
|
|
||||||
+ memset(&info, 0, sizeof(info));
|
|
||||||
+ info.acpi_node.companion = adev;
|
|
||||||
+ info.irq = -1;
|
|
||||||
+
|
|
||||||
+ INIT_LIST_HEAD(&resource_list);
|
|
||||||
+ ret = acpi_dev_get_resources(adev, &resource_list,
|
|
||||||
+ acpi_i2c_add_resource, &info);
|
|
||||||
+ acpi_dev_free_resource_list(&resource_list);
|
|
||||||
+
|
|
||||||
+ if (ret < 0 || !info.addr)
|
|
||||||
+ return AE_OK;
|
|
||||||
+
|
|
||||||
+ adev->power.flags.ignore_parent = true;
|
|
||||||
+ strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
|
|
||||||
+ if (!i2c_new_device(adapter, &info)) {
|
|
||||||
+ adev->power.flags.ignore_parent = false;
|
|
||||||
+ dev_err(&adapter->dev,
|
|
||||||
+ "failed to add I2C device %s from ACPI\n",
|
|
||||||
+ dev_name(&adev->dev));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return AE_OK;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
|
|
||||||
+ * @adap: pointer to adapter
|
|
||||||
+ *
|
|
||||||
+ * Enumerate all I2C slave devices behind this adapter by walking the ACPI
|
|
||||||
+ * namespace. When a device is found it will be added to the Linux device
|
|
||||||
+ * model and bound to the corresponding ACPI handle.
|
|
||||||
+ */
|
|
||||||
+void acpi_i2c_register_devices(struct i2c_adapter *adap)
|
|
||||||
+{
|
|
||||||
+ acpi_handle handle;
|
|
||||||
+ acpi_status status;
|
|
||||||
+
|
|
||||||
+ if (!adap->dev.parent)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ handle = ACPI_HANDLE(adap->dev.parent);
|
|
||||||
+ if (!handle)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
|
|
||||||
+ acpi_i2c_add_device, NULL,
|
|
||||||
+ adap, NULL);
|
|
||||||
+ if (ACPI_FAILURE(status))
|
|
||||||
+ dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
|
|
||||||
u8 cmd, u8 *data, u8 data_len)
|
|
||||||
{
|
|
||||||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
|
|
||||||
index e25cb84..4ccff11 100644
|
|
||||||
--- a/drivers/i2c/i2c-core.c
|
|
||||||
+++ b/drivers/i2c/i2c-core.c
|
|
||||||
@@ -1092,101 +1092,6 @@ EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
|
|
||||||
static void of_i2c_register_devices(struct i2c_adapter *adap) { }
|
|
||||||
#endif /* CONFIG_OF */
|
|
||||||
|
|
||||||
-/* ACPI support code */
|
|
||||||
-
|
|
||||||
-#if IS_ENABLED(CONFIG_ACPI)
|
|
||||||
-static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
|
|
||||||
-{
|
|
||||||
- struct i2c_board_info *info = data;
|
|
||||||
-
|
|
||||||
- if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
|
|
||||||
- struct acpi_resource_i2c_serialbus *sb;
|
|
||||||
-
|
|
||||||
- sb = &ares->data.i2c_serial_bus;
|
|
||||||
- if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
|
|
||||||
- info->addr = sb->slave_address;
|
|
||||||
- if (sb->access_mode == ACPI_I2C_10BIT_MODE)
|
|
||||||
- info->flags |= I2C_CLIENT_TEN;
|
|
||||||
- }
|
|
||||||
- } else if (info->irq < 0) {
|
|
||||||
- struct resource r;
|
|
||||||
-
|
|
||||||
- if (acpi_dev_resource_interrupt(ares, 0, &r))
|
|
||||||
- info->irq = r.start;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Tell the ACPI core to skip this resource */
|
|
||||||
- return 1;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
|
|
||||||
- void *data, void **return_value)
|
|
||||||
-{
|
|
||||||
- struct i2c_adapter *adapter = data;
|
|
||||||
- struct list_head resource_list;
|
|
||||||
- struct i2c_board_info info;
|
|
||||||
- struct acpi_device *adev;
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
- if (acpi_bus_get_device(handle, &adev))
|
|
||||||
- return AE_OK;
|
|
||||||
- if (acpi_bus_get_status(adev) || !adev->status.present)
|
|
||||||
- return AE_OK;
|
|
||||||
-
|
|
||||||
- memset(&info, 0, sizeof(info));
|
|
||||||
- info.acpi_node.companion = adev;
|
|
||||||
- info.irq = -1;
|
|
||||||
-
|
|
||||||
- INIT_LIST_HEAD(&resource_list);
|
|
||||||
- ret = acpi_dev_get_resources(adev, &resource_list,
|
|
||||||
- acpi_i2c_add_resource, &info);
|
|
||||||
- acpi_dev_free_resource_list(&resource_list);
|
|
||||||
-
|
|
||||||
- if (ret < 0 || !info.addr)
|
|
||||||
- return AE_OK;
|
|
||||||
-
|
|
||||||
- adev->power.flags.ignore_parent = true;
|
|
||||||
- strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
|
|
||||||
- if (!i2c_new_device(adapter, &info)) {
|
|
||||||
- adev->power.flags.ignore_parent = false;
|
|
||||||
- dev_err(&adapter->dev,
|
|
||||||
- "failed to add I2C device %s from ACPI\n",
|
|
||||||
- dev_name(&adev->dev));
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return AE_OK;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/**
|
|
||||||
- * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
|
|
||||||
- * @adap: pointer to adapter
|
|
||||||
- *
|
|
||||||
- * Enumerate all I2C slave devices behind this adapter by walking the ACPI
|
|
||||||
- * namespace. When a device is found it will be added to the Linux device
|
|
||||||
- * model and bound to the corresponding ACPI handle.
|
|
||||||
- */
|
|
||||||
-static void acpi_i2c_register_devices(struct i2c_adapter *adap)
|
|
||||||
-{
|
|
||||||
- acpi_handle handle;
|
|
||||||
- acpi_status status;
|
|
||||||
-
|
|
||||||
- if (!adap->dev.parent)
|
|
||||||
- return;
|
|
||||||
-
|
|
||||||
- handle = ACPI_HANDLE(adap->dev.parent);
|
|
||||||
- if (!handle)
|
|
||||||
- return;
|
|
||||||
-
|
|
||||||
- status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
|
|
||||||
- acpi_i2c_add_device, NULL,
|
|
||||||
- adap, NULL);
|
|
||||||
- if (ACPI_FAILURE(status))
|
|
||||||
- dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
|
|
||||||
-}
|
|
||||||
-#else
|
|
||||||
-static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
|
|
||||||
-#endif /* CONFIG_ACPI */
|
|
||||||
-
|
|
||||||
static int i2c_do_add_adapter(struct i2c_driver *driver,
|
|
||||||
struct i2c_adapter *adap)
|
|
||||||
{
|
|
||||||
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
|
|
||||||
index f7a939a..ea50766 100644
|
|
||||||
--- a/include/linux/i2c.h
|
|
||||||
+++ b/include/linux/i2c.h
|
|
||||||
@@ -577,10 +577,12 @@ static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_OF */
|
|
||||||
|
|
||||||
-#ifdef CONFIG_ACPI
|
|
||||||
+#ifdef CONFIG_I2C_ACPI
|
|
||||||
int acpi_i2c_install_space_handler(struct i2c_adapter *adapter);
|
|
||||||
void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter);
|
|
||||||
+void acpi_i2c_register_devices(struct i2c_adapter *adap);
|
|
||||||
#else
|
|
||||||
+static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) { }
|
|
||||||
static inline void acpi_i2c_remove_space_handler(struct i2c_adapter *adapter)
|
|
||||||
{ }
|
|
||||||
static inline int acpi_i2c_install_space_handler(struct i2c_adapter *adapter)
|
|
39
kernel.spec
39
kernel.spec
@ -628,17 +628,6 @@ Patch30000: kernel-arm64.patch
|
|||||||
|
|
||||||
# AWB PATCH DEFINITIONS (BAYTRAIL)
|
# AWB PATCH DEFINITIONS (BAYTRAIL)
|
||||||
|
|
||||||
# Fixes shutdown and reboot, without quirks
|
|
||||||
# https://bugzilla.kernel.org/show_bug.cgi?id=70931
|
|
||||||
# https://patchwork.kernel.org/patch/3787341/
|
|
||||||
Patch31000: x86-new-Intel-Atom-SoC-power-management-controller-driver.patch
|
|
||||||
|
|
||||||
# Battery status support patch series from Lan Tianyu
|
|
||||||
# https://bugzilla.kernel.org/show_bug.cgi?id=69011
|
|
||||||
# https://lkml.org/lkml/2014/5/20/284
|
|
||||||
# patches 1-3 already merged upstream
|
|
||||||
Patch31001: V3-4-5-I2C-ACPI-Add-i2c-ACPI-operation-region-support.patch
|
|
||||||
Patch31002: V3-5-5-I2C-ACPI-Clean-up-I2C-ACPI-code-and-Add-CONFIG_I2C_ACPI-config.patch
|
|
||||||
# http://www.spinics.net/lists/linux-i2c/msg15201.html
|
# http://www.spinics.net/lists/linux-i2c/msg15201.html
|
||||||
Patch31010: 0001-ACPI-temporary-dep-solution-for-battery-support.patch
|
Patch31010: 0001-ACPI-temporary-dep-solution-for-battery-support.patch
|
||||||
|
|
||||||
@ -646,19 +635,6 @@ Patch31010: 0001-ACPI-temporary-dep-solution-for-battery-support.patch
|
|||||||
# https://bugzilla.kernel.org/show_bug.cgi?id=67921
|
# https://bugzilla.kernel.org/show_bug.cgi?id=67921
|
||||||
Patch31011: baytrail_gpio_quirk_v3.patch
|
Patch31011: baytrail_gpio_quirk_v3.patch
|
||||||
|
|
||||||
# Update name of audio firmware file
|
|
||||||
# http://comments.gmane.org/gmane.linux.alsa.devel/126117
|
|
||||||
# Upstream 3.17
|
|
||||||
Patch31012: ASoC-Intel-update-baytrail-adsp-firmware-name.patch
|
|
||||||
|
|
||||||
# ath6kl series backported from 3.17, should make wireless work
|
|
||||||
Patch31101: 0001-ath6kl-Fix-ath6kl_bmi_read_hi32-macro.patch
|
|
||||||
Patch31102: 0002-ath6kl-convert-ar6004-hardware-flags-to-firmware-fea.patch
|
|
||||||
Patch31103: 0003-ath6kl-implement-rx-flush-for-htc-pipe.patch
|
|
||||||
Patch31104: 0004-ath6kl-don-t-set-hi_refclk_hz-if-hardware-version-do.patch
|
|
||||||
Patch31105: 0005-ath6kl-add-support-wmi-rate-tables-with-mcs15.patch
|
|
||||||
Patch31106: 0006-ath6kl-add-support-for-ar6004-hw3.0.patch
|
|
||||||
|
|
||||||
# Add SDIO ID for the V8P wireless adapter to ath6kl driver
|
# Add SDIO ID for the V8P wireless adapter to ath6kl driver
|
||||||
Patch31200: support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch
|
Patch31200: support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch
|
||||||
|
|
||||||
@ -1402,25 +1378,10 @@ ApplyPatch kernel-arm64.patch -R
|
|||||||
# END OF FEDORA PATCH APPLICATIONS
|
# END OF FEDORA PATCH APPLICATIONS
|
||||||
|
|
||||||
# AWB (BAYTRAIL) PATCH APPLICATIONS
|
# AWB (BAYTRAIL) PATCH APPLICATIONS
|
||||||
ApplyPatch V3-4-5-I2C-ACPI-Add-i2c-ACPI-operation-region-support.patch
|
|
||||||
# Not applied as it causes all kinds of config file chaos, and I've never seen
|
|
||||||
# the hang/crash that allegedly happens without it...
|
|
||||||
#ApplyPatch V3-5-5-I2C-ACPI-Clean-up-I2C-ACPI-code-and-Add-CONFIG_I2C_ACPI-config.patch
|
|
||||||
ApplyPatch x86-new-Intel-Atom-SoC-power-management-controller-driver.patch
|
|
||||||
|
|
||||||
ApplyPatch 0001-ACPI-temporary-dep-solution-for-battery-support.patch
|
ApplyPatch 0001-ACPI-temporary-dep-solution-for-battery-support.patch
|
||||||
# Doesn't apply cleanly to 3.16
|
# Doesn't apply cleanly to 3.16
|
||||||
#ApplyPatch baytrail_gpio_quirk_v3.patch
|
#ApplyPatch baytrail_gpio_quirk_v3.patch
|
||||||
|
|
||||||
ApplyPatch ASoC-Intel-update-baytrail-adsp-firmware-name.patch
|
|
||||||
|
|
||||||
ApplyPatch 0001-ath6kl-Fix-ath6kl_bmi_read_hi32-macro.patch
|
|
||||||
ApplyPatch 0002-ath6kl-convert-ar6004-hardware-flags-to-firmware-fea.patch
|
|
||||||
ApplyPatch 0003-ath6kl-implement-rx-flush-for-htc-pipe.patch
|
|
||||||
ApplyPatch 0004-ath6kl-don-t-set-hi_refclk_hz-if-hardware-version-do.patch
|
|
||||||
ApplyPatch 0005-ath6kl-add-support-wmi-rate-tables-with-mcs15.patch
|
|
||||||
ApplyPatch 0006-ath6kl-add-support-for-ar6004-hw3.0.patch
|
|
||||||
|
|
||||||
ApplyPatch support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch
|
ApplyPatch support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch
|
||||||
|
|
||||||
# END OF AWB (BAYTRAIL) PATCH APPLICATIONS
|
# END OF AWB (BAYTRAIL) PATCH APPLICATIONS
|
||||||
|
@ -1,484 +0,0 @@
|
|||||||
From patchwork Fri Mar 7 03:04:42 2014
|
|
||||||
Content-Type: text/plain; charset="utf-8"
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Transfer-Encoding: 7bit
|
|
||||||
Subject: x86: new Intel Atom SoC power management controller driver
|
|
||||||
From: "Li, Aubrey" <aubrey.li@linux.intel.com>
|
|
||||||
X-Patchwork-Id: 3787341
|
|
||||||
Message-Id: <5319374A.60308@linux.intel.com>
|
|
||||||
To: Joe Perches <joe@perches.com>
|
|
||||||
Cc: "H. Peter Anvin" <hpa@linux.intel.com>,
|
|
||||||
Matthew Garrett <mjg59@srcf.ucam.org>, mingo@redhat.com,
|
|
||||||
tglx@linutronix.de, linux-kernel@vger.kernel.org,
|
|
||||||
"alan@linux.intel.com" <alan@linux.intel.com>
|
|
||||||
Date: Fri, 07 Mar 2014 11:04:42 +0800
|
|
||||||
|
|
||||||
On 2014/3/7 10:21, Joe Perches wrote:
|
|
||||||
> On Fri, 2014-03-07 at 10:08 +0800, Li, Aubrey wrote:
|
|
||||||
>
|
|
||||||
>> The Power Management Controller (PMC) controls many of the power
|
|
||||||
>> management features present in the SoC. This driver provides
|
|
||||||
>> interface to configure the Power Management Controller (PMC).
|
|
||||||
>
|
|
||||||
> More trivial notes.
|
|
||||||
>
|
|
||||||
> Nothing really that should stop this from being applied.
|
|
||||||
>
|
|
||||||
All make sense to me. Welcome your more comments, Joe!
|
|
||||||
|
|
||||||
Thanks,
|
|
||||||
-Aubrey
|
|
||||||
|
|
||||||
[PATCH] X86 platform: New Intel Atom SOC power management controller driver
|
|
||||||
|
|
||||||
The Power Management Controller (PMC) controls many of the power
|
|
||||||
management features present in the SoC. This driver provides
|
|
||||||
interface to configure the Power Management Controller (PMC).
|
|
||||||
|
|
||||||
This driver exposes PMC device state and sleep state residency
|
|
||||||
via debugfs:
|
|
||||||
/sys/kernel/debugfs/pmc_atom/dev_state
|
|
||||||
/sys/kernel/debugfs/pmc_atom/sleep_state
|
|
||||||
|
|
||||||
This driver also provides a native power off function via PMC PCI
|
|
||||||
IO port.
|
|
||||||
|
|
||||||
Signed-off-by: Aubrey Li <aubrey.li@intel.com>
|
|
||||||
Reviewed-by: Joe Perches <joe@perches.com>
|
|
||||||
|
|
||||||
---
|
|
||||||
arch/x86/Kconfig | 4 +
|
|
||||||
arch/x86/include/asm/pmc_atom.h | 91 ++++++++++++
|
|
||||||
arch/x86/kernel/Makefile | 1 +
|
|
||||||
arch/x86/kernel/pmc_atom.c | 297 +++++++++++++++++++++++++++++++++++++++
|
|
||||||
4 files changed, 393 insertions(+)
|
|
||||||
create mode 100644 arch/x86/include/asm/pmc_atom.h
|
|
||||||
create mode 100644 arch/x86/kernel/pmc_atom.c
|
|
||||||
|
|
||||||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
|
|
||||||
index 0af5250..18f7d38 100644
|
|
||||||
--- a/arch/x86/Kconfig
|
|
||||||
+++ b/arch/x86/Kconfig
|
|
||||||
@@ -2413,6 +2413,10 @@
|
|
||||||
tristate
|
|
||||||
default m
|
|
||||||
depends on PCI
|
|
||||||
+
|
|
||||||
+config PMC_ATOM
|
|
||||||
+ def_bool y
|
|
||||||
+ depends on PCI
|
|
||||||
|
|
||||||
source "net/Kconfig"
|
|
||||||
|
|
||||||
diff --git a/arch/x86/include/asm/pmc_atom.h b/arch/x86/include/asm/pmc_atom.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..43b68fc
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/arch/x86/include/asm/pmc_atom.h
|
|
||||||
@@ -0,0 +1,91 @@
|
|
||||||
+/*
|
|
||||||
+ * Intel Atom SOC Power Management Controller Header File
|
|
||||||
+ * Copyright (c) 2014, Intel Corporation.
|
|
||||||
+ *
|
|
||||||
+ * This program is free software; you can redistribute it and/or modify it
|
|
||||||
+ * under the terms and conditions of the GNU General Public License,
|
|
||||||
+ * version 2, as published by the Free Software Foundation.
|
|
||||||
+ *
|
|
||||||
+ * This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
+ * more details.
|
|
||||||
+ *
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef PMC_ATOM_H
|
|
||||||
+#define PMC_ATOM_H
|
|
||||||
+
|
|
||||||
+/* ValleyView Power Control Unit PCI Device ID */
|
|
||||||
+#define PCI_DEVICE_ID_VLV_PMC 0x0F1C
|
|
||||||
+
|
|
||||||
+/* PMC Memory mapped IO registers */
|
|
||||||
+#define PMC_BASE_ADDR_OFFSET 0x44
|
|
||||||
+#define PMC_BASE_ADDR_MASK 0xFFFFFE00
|
|
||||||
+#define PMC_MMIO_REG_LEN 0x100
|
|
||||||
+#define PMC_REG_BIT_WIDTH 32
|
|
||||||
+
|
|
||||||
+/* BIOS uses FUNC_DIS to disable specific function */
|
|
||||||
+#define PMC_FUNC_DIS 0x34
|
|
||||||
+#define PMC_FUNC_DIS_2 0x38
|
|
||||||
+/* The timers acumulate time spent in sleep state */
|
|
||||||
+#define PMC_S0IR_TMR 0x80
|
|
||||||
+#define PMC_S0I1_TMR 0x84
|
|
||||||
+#define PMC_S0I2_TMR 0x88
|
|
||||||
+#define PMC_S0I3_TMR 0x8C
|
|
||||||
+#define PMC_S0_TMR 0x90
|
|
||||||
+/* Sleep state counter is in units of of 32us */
|
|
||||||
+#define PMC_TMR_SHIFT 5
|
|
||||||
+
|
|
||||||
+/* These registers reflect D3 status of functions */
|
|
||||||
+#define PMC_D3_STS_0 0xA0
|
|
||||||
+
|
|
||||||
+#define BIT_LPSS1_F0_DMA BIT(0)
|
|
||||||
+#define BIT_LPSS1_F1_PWM1 BIT(1)
|
|
||||||
+#define BIT_LPSS1_F2_PWM2 BIT(2)
|
|
||||||
+#define BIT_LPSS1_F3_HSUART1 BIT(3)
|
|
||||||
+#define BIT_LPSS1_F4_HSUART2 BIT(4)
|
|
||||||
+#define BIT_LPSS1_F5_SPI BIT(5)
|
|
||||||
+#define BIT_LPSS1_F6_XXX BIT(6)
|
|
||||||
+#define BIT_LPSS1_F7_XXX BIT(7)
|
|
||||||
+#define BIT_SCC_EMMC BIT(8)
|
|
||||||
+#define BIT_SCC_SDIO BIT(9)
|
|
||||||
+#define BIT_SCC_SDCARD BIT(10)
|
|
||||||
+#define BIT_SCC_MIPI BIT(11)
|
|
||||||
+#define BIT_HDA BIT(12)
|
|
||||||
+#define BIT_LPE BIT(13)
|
|
||||||
+#define BIT_OTG BIT(14)
|
|
||||||
+#define BIT_USH BIT(15)
|
|
||||||
+#define BIT_GBE BIT(16)
|
|
||||||
+#define BIT_SATA BIT(17)
|
|
||||||
+#define BIT_USB_EHCI BIT(18)
|
|
||||||
+#define BIT_SEC BIT(19)
|
|
||||||
+#define BIT_PCIE_PORT0 BIT(20)
|
|
||||||
+#define BIT_PCIE_PORT1 BIT(21)
|
|
||||||
+#define BIT_PCIE_PORT2 BIT(22)
|
|
||||||
+#define BIT_PCIE_PORT3 BIT(23)
|
|
||||||
+#define BIT_LPSS2_F0_DMA BIT(24)
|
|
||||||
+#define BIT_LPSS2_F1_I2C1 BIT(25)
|
|
||||||
+#define BIT_LPSS2_F2_I2C2 BIT(26)
|
|
||||||
+#define BIT_LPSS2_F3_I2C3 BIT(27)
|
|
||||||
+#define BIT_LPSS2_F4_I2C4 BIT(28)
|
|
||||||
+#define BIT_LPSS2_F5_I2C5 BIT(29)
|
|
||||||
+#define BIT_LPSS2_F6_I2C6 BIT(30)
|
|
||||||
+#define BIT_LPSS2_F7_I2C7 BIT(31)
|
|
||||||
+
|
|
||||||
+#define PMC_D3_STS_1 0xA4
|
|
||||||
+#define BIT_SMB BIT(0)
|
|
||||||
+#define BIT_USH_SS_PHY BIT(1)
|
|
||||||
+#define BIT_OTG_SS_PHY BIT(2)
|
|
||||||
+#define BIT_DFX BIT(3)
|
|
||||||
+
|
|
||||||
+/* PMC I/O Registers */
|
|
||||||
+#define ACPI_BASE_ADDR_OFFSET 0x40
|
|
||||||
+#define ACPI_BASE_ADDR_MASK 0xFFFFFE00
|
|
||||||
+#define ACPI_MMIO_REG_LEN 0x100
|
|
||||||
+
|
|
||||||
+#define PM1_CNT 0x4
|
|
||||||
+#define SLEEP_TYPE_MASK 0xFFFFECFF
|
|
||||||
+#define SLEEP_TYPE_S5 0x1C00
|
|
||||||
+#define SLEEP_ENABLE 0x2000
|
|
||||||
+#endif /* PMC_ATOM_H */
|
|
||||||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
|
|
||||||
index cb648c8..b71a61a 100644
|
|
||||||
--- a/arch/x86/kernel/Makefile
|
|
||||||
+++ b/arch/x86/kernel/Makefile
|
|
||||||
@@ -104,6 +104,7 @@ obj-$(CONFIG_EFI) += sysfb_efi.o
|
|
||||||
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
|
|
||||||
obj-$(CONFIG_TRACING) += tracepoint.o
|
|
||||||
obj-$(CONFIG_IOSF_MBI) += iosf_mbi.o
|
|
||||||
+obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
|
|
||||||
|
|
||||||
###
|
|
||||||
# 64 bit specific files
|
|
||||||
diff --git a/arch/x86/kernel/pmc_atom.c b/arch/x86/kernel/pmc_atom.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..5991030
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/arch/x86/kernel/pmc_atom.c
|
|
||||||
@@ -0,0 +1,297 @@
|
|
||||||
+/*
|
|
||||||
+ * Intel Atom SOC Power Management Controller Driver
|
|
||||||
+ * Copyright (c) 2014, Intel Corporation.
|
|
||||||
+ *
|
|
||||||
+ * This program is free software; you can redistribute it and/or modify it
|
|
||||||
+ * under the terms and conditions of the GNU General Public License,
|
|
||||||
+ * version 2, as published by the Free Software Foundation.
|
|
||||||
+ *
|
|
||||||
+ * This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
+ * more details.
|
|
||||||
+ *
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
||||||
+
|
|
||||||
+#include <linux/module.h>
|
|
||||||
+#include <linux/init.h>
|
|
||||||
+#include <linux/pci.h>
|
|
||||||
+#include <linux/device.h>
|
|
||||||
+#include <linux/debugfs.h>
|
|
||||||
+#include <linux/seq_file.h>
|
|
||||||
+#include <linux/io.h>
|
|
||||||
+
|
|
||||||
+#include <asm/pmc_atom.h>
|
|
||||||
+
|
|
||||||
+#define DRIVER_NAME KBUILD_MODNAME
|
|
||||||
+
|
|
||||||
+struct pmc_dev {
|
|
||||||
+ struct pci_dev *pdev;
|
|
||||||
+ u32 base_addr;
|
|
||||||
+ void __iomem *regmap;
|
|
||||||
+#ifdef CONFIG_DEBUG_FS
|
|
||||||
+ struct dentry *dbgfs_dir;
|
|
||||||
+#endif /* CONFIG_DEBUG_FS */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static u32 acpi_base_addr;
|
|
||||||
+
|
|
||||||
+struct pmc_dev_map {
|
|
||||||
+ const char *name;
|
|
||||||
+ u32 bit_mask;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct pmc_dev_map dev_map[] = {
|
|
||||||
+ {"0 - LPSS1_F0_DMA", BIT_LPSS1_F0_DMA},
|
|
||||||
+ {"1 - LPSS1_F1_PWM1", BIT_LPSS1_F1_PWM1},
|
|
||||||
+ {"2 - LPSS1_F2_PWM2", BIT_LPSS1_F2_PWM2},
|
|
||||||
+ {"3 - LPSS1_F3_HSUART1", BIT_LPSS1_F3_HSUART1},
|
|
||||||
+ {"4 - LPSS1_F4_HSUART2", BIT_LPSS1_F4_HSUART2},
|
|
||||||
+ {"5 - LPSS1_F5_SPI", BIT_LPSS1_F5_SPI},
|
|
||||||
+ {"6 - LPSS1_F6_Reserved", BIT_LPSS1_F6_XXX},
|
|
||||||
+ {"7 - LPSS1_F7_Reserved", BIT_LPSS1_F7_XXX},
|
|
||||||
+ {"8 - SCC_EMMC", BIT_SCC_EMMC},
|
|
||||||
+ {"9 - SCC_SDIO", BIT_SCC_SDIO},
|
|
||||||
+ {"10 - SCC_SDCARD", BIT_SCC_SDCARD},
|
|
||||||
+ {"11 - SCC_MIPI", BIT_SCC_MIPI},
|
|
||||||
+ {"12 - HDA", BIT_HDA},
|
|
||||||
+ {"13 - LPE", BIT_LPE},
|
|
||||||
+ {"14 - OTG", BIT_OTG},
|
|
||||||
+ {"15 - USH", BIT_USH},
|
|
||||||
+ {"16 - GBE", BIT_GBE},
|
|
||||||
+ {"17 - SATA", BIT_SATA},
|
|
||||||
+ {"18 - USB_EHCI", BIT_USB_EHCI},
|
|
||||||
+ {"19 - SEC", BIT_SEC},
|
|
||||||
+ {"20 - PCIE_PORT0", BIT_PCIE_PORT0},
|
|
||||||
+ {"21 - PCIE_PORT1", BIT_PCIE_PORT1},
|
|
||||||
+ {"22 - PCIE_PORT2", BIT_PCIE_PORT2},
|
|
||||||
+ {"23 - PCIE_PORT3", BIT_PCIE_PORT3},
|
|
||||||
+ {"24 - LPSS2_F0_DMA", BIT_LPSS2_F0_DMA},
|
|
||||||
+ {"25 - LPSS2_F1_I2C1", BIT_LPSS2_F1_I2C1},
|
|
||||||
+ {"26 - LPSS2_F2_I2C2", BIT_LPSS2_F2_I2C2},
|
|
||||||
+ {"27 - LPSS2_F3_I2C3", BIT_LPSS2_F3_I2C3},
|
|
||||||
+ {"28 - LPSS2_F3_I2C4", BIT_LPSS2_F4_I2C4},
|
|
||||||
+ {"29 - LPSS2_F5_I2C5", BIT_LPSS2_F5_I2C5},
|
|
||||||
+ {"30 - LPSS2_F6_I2C6", BIT_LPSS2_F6_I2C6},
|
|
||||||
+ {"31 - LPSS2_F7_I2C7", BIT_LPSS2_F7_I2C7},
|
|
||||||
+ {"32 - SMB", BIT_SMB},
|
|
||||||
+ {"33 - USH_SS_PHY", BIT_OTG_SS_PHY},
|
|
||||||
+ {"34 - OTG_SS_PHY", BIT_USH_SS_PHY},
|
|
||||||
+ {"35 - DFX", BIT_DFX},
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
|
|
||||||
+{
|
|
||||||
+ return readl(pmc->regmap + reg_offset);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void pmc_power_off(void)
|
|
||||||
+{
|
|
||||||
+ u16 pm1_cnt_port;
|
|
||||||
+ u32 pm1_cnt_value;
|
|
||||||
+
|
|
||||||
+ pr_info("Preparing to enter system sleep state S5\n");
|
|
||||||
+
|
|
||||||
+ pm1_cnt_port = acpi_base_addr + PM1_CNT;
|
|
||||||
+
|
|
||||||
+ pm1_cnt_value = inl(pm1_cnt_port);
|
|
||||||
+ pm1_cnt_value &= SLEEP_TYPE_MASK;
|
|
||||||
+ pm1_cnt_value |= SLEEP_TYPE_S5;
|
|
||||||
+ pm1_cnt_value |= SLEEP_ENABLE;
|
|
||||||
+
|
|
||||||
+ outl(pm1_cnt_value, pm1_cnt_port);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#ifdef CONFIG_DEBUG_FS
|
|
||||||
+static int pmc_dev_state_show(struct seq_file *s, void *unused)
|
|
||||||
+{
|
|
||||||
+ struct pmc_dev *pmc = (struct pmc_dev *)s->private;
|
|
||||||
+ u32 func_dis, func_dis_2, func_dis_index;
|
|
||||||
+ u32 d3_sts_0, d3_sts_1, d3_sts_index;
|
|
||||||
+ int dev_num, dev_index, reg_index;
|
|
||||||
+
|
|
||||||
+ func_dis = pmc_reg_read(pmc, PMC_FUNC_DIS);
|
|
||||||
+ func_dis_2 = pmc_reg_read(pmc, PMC_FUNC_DIS_2);
|
|
||||||
+ d3_sts_0 = pmc_reg_read(pmc, PMC_D3_STS_0);
|
|
||||||
+ d3_sts_1 = pmc_reg_read(pmc, PMC_D3_STS_1);
|
|
||||||
+
|
|
||||||
+ dev_num = sizeof(dev_map) / sizeof(struct pmc_dev_map);
|
|
||||||
+
|
|
||||||
+ for (dev_index = 0; dev_index < dev_num; dev_index++) {
|
|
||||||
+ reg_index = dev_index / PMC_REG_BIT_WIDTH;
|
|
||||||
+ if (reg_index) {
|
|
||||||
+ func_dis_index = func_dis_2;
|
|
||||||
+ d3_sts_index = d3_sts_1;
|
|
||||||
+ } else {
|
|
||||||
+ func_dis_index = func_dis;
|
|
||||||
+ d3_sts_index = d3_sts_0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ seq_printf(s, "Dev: %-32s\tState: %s [%s]\n",
|
|
||||||
+ dev_map[dev_index].name,
|
|
||||||
+ dev_map[dev_index].bit_mask & func_dis_index ?
|
|
||||||
+ "Disabled" : "Enabled ",
|
|
||||||
+ dev_map[dev_index].bit_mask & d3_sts_index ?
|
|
||||||
+ "D3" : "D0");
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int pmc_dev_state_open(struct inode *inode, struct file *file)
|
|
||||||
+{
|
|
||||||
+ return single_open(file, pmc_dev_state_show, inode->i_private);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct file_operations pmc_dev_state_ops = {
|
|
||||||
+ .open = pmc_dev_state_open,
|
|
||||||
+ .read = seq_read,
|
|
||||||
+ .llseek = seq_lseek,
|
|
||||||
+ .release = single_release,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int pmc_sleep_tmr_show(struct seq_file *s, void *unused)
|
|
||||||
+{
|
|
||||||
+ struct pmc_dev *pmc = (struct pmc_dev *)s->private;
|
|
||||||
+ u64 s0ir_tmr, s0i1_tmr, s0i2_tmr, s0i3_tmr, s0_tmr;
|
|
||||||
+
|
|
||||||
+ s0ir_tmr = pmc_reg_read(pmc, PMC_S0IR_TMR) << PMC_TMR_SHIFT;
|
|
||||||
+ s0i1_tmr = pmc_reg_read(pmc, PMC_S0I1_TMR) << PMC_TMR_SHIFT;
|
|
||||||
+ s0i2_tmr = pmc_reg_read(pmc, PMC_S0I2_TMR) << PMC_TMR_SHIFT;
|
|
||||||
+ s0i3_tmr = pmc_reg_read(pmc, PMC_S0I3_TMR) << PMC_TMR_SHIFT;
|
|
||||||
+ s0_tmr = pmc_reg_read(pmc, PMC_S0_TMR) << PMC_TMR_SHIFT;
|
|
||||||
+
|
|
||||||
+ seq_printf(s, "S0IR Residency:\t%lldus\n", s0ir_tmr);
|
|
||||||
+ seq_printf(s, "S0I1 Residency:\t%lldus\n", s0i1_tmr);
|
|
||||||
+ seq_printf(s, "S0I2 Residency:\t%lldus\n", s0i2_tmr);
|
|
||||||
+ seq_printf(s, "S0I3 Residency:\t%lldus\n", s0i3_tmr);
|
|
||||||
+ seq_printf(s, "S0 Residency:\t%lldus\n", s0_tmr);
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int pmc_sleep_tmr_open(struct inode *inode, struct file *file)
|
|
||||||
+{
|
|
||||||
+ return single_open(file, pmc_sleep_tmr_show, inode->i_private);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct file_operations pmc_sleep_tmr_ops = {
|
|
||||||
+ .open = pmc_sleep_tmr_open,
|
|
||||||
+ .read = seq_read,
|
|
||||||
+ .llseek = seq_lseek,
|
|
||||||
+ .release = single_release,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static void pmc_dbgfs_unregister(struct pmc_dev *pmc)
|
|
||||||
+{
|
|
||||||
+ if (!pmc->dbgfs_dir)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ debugfs_remove_recursive(pmc->dbgfs_dir);
|
|
||||||
+ pmc->dbgfs_dir = NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int pmc_dbgfs_register(struct pmc_dev *pmc)
|
|
||||||
+{
|
|
||||||
+ struct dentry *dir, *f;
|
|
||||||
+
|
|
||||||
+ dir = debugfs_create_dir("pmc_atom", NULL);
|
|
||||||
+ if (!dir)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ f = debugfs_create_file("dev_state", S_IFREG | S_IRUGO,
|
|
||||||
+ dir, pmc, &pmc_dev_state_ops);
|
|
||||||
+ if (!f) {
|
|
||||||
+ dev_err(&pmc->pdev->dev, "dev_states register failed\n");
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
+ f = debugfs_create_file("sleep_state", S_IFREG | S_IRUGO,
|
|
||||||
+ dir, pmc, &pmc_sleep_tmr_ops);
|
|
||||||
+ if (!f) {
|
|
||||||
+ dev_err(&pmc->pdev->dev, "sleep_state register failed\n");
|
|
||||||
+ goto err;
|
|
||||||
+ }
|
|
||||||
+ pmc->dbgfs_dir = dir;
|
|
||||||
+ return 0;
|
|
||||||
+err:
|
|
||||||
+ pmc_dbgfs_unregister(pmc);
|
|
||||||
+ return -ENODEV;
|
|
||||||
+}
|
|
||||||
+#endif /* CONFIG_DEBUG_FS */
|
|
||||||
+
|
|
||||||
+static int pmc_probe(struct pci_dev *pdev,
|
|
||||||
+ const struct pci_device_id *unused)
|
|
||||||
+{
|
|
||||||
+ struct pmc_dev *pmc;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = pci_enable_device(pdev);
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ dev_err(&pdev->dev, "error: could not enable device\n");
|
|
||||||
+ goto err_enable_device;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = pci_request_regions(pdev, DRIVER_NAME);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(&pdev->dev, "error: could not request PCI region\n");
|
|
||||||
+ goto err_request_regions;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pmc = devm_kzalloc(&pdev->dev, sizeof(struct pmc_dev), GFP_KERNEL);
|
|
||||||
+ if (!pmc) {
|
|
||||||
+ ret = -ENOMEM;
|
|
||||||
+ goto err_devm_kzalloc;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pmc->pdev = pci_dev_get(pdev);
|
|
||||||
+
|
|
||||||
+ pci_read_config_dword(pdev, PMC_BASE_ADDR_OFFSET, &pmc->base_addr);
|
|
||||||
+ pmc->base_addr &= PMC_BASE_ADDR_MASK;
|
|
||||||
+
|
|
||||||
+ pmc->regmap = devm_ioremap_nocache(&pdev->dev,
|
|
||||||
+ pmc->base_addr, PMC_MMIO_REG_LEN);
|
|
||||||
+ if (!pmc->regmap) {
|
|
||||||
+ dev_err(&pdev->dev, "error: ioremap failed\n");
|
|
||||||
+ ret = -ENOMEM;
|
|
||||||
+ goto err_devm_ioremap;
|
|
||||||
+ }
|
|
||||||
+ pci_set_drvdata(pdev, pmc);
|
|
||||||
+#ifdef CONFIG_DEBUG_FS
|
|
||||||
+ pmc_dbgfs_register(pmc);
|
|
||||||
+#endif /* CONFIG_DEBUG_FS */
|
|
||||||
+
|
|
||||||
+ /* Install power off function */
|
|
||||||
+ pci_read_config_dword(pdev, ACPI_BASE_ADDR_OFFSET, &acpi_base_addr);
|
|
||||||
+ acpi_base_addr &= ACPI_BASE_ADDR_MASK;
|
|
||||||
+ if (acpi_base_addr != 0 && pm_power_off == NULL)
|
|
||||||
+ pm_power_off = pmc_power_off;
|
|
||||||
+ return 0;
|
|
||||||
+err_devm_ioremap:
|
|
||||||
+ pci_dev_put(pdev);
|
|
||||||
+err_devm_kzalloc:
|
|
||||||
+ pci_release_regions(pdev);
|
|
||||||
+err_request_regions:
|
|
||||||
+ pci_disable_device(pdev);
|
|
||||||
+err_enable_device:
|
|
||||||
+ dev_err(&pdev->dev, "error: probe failed\n");
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct pci_device_id pmc_pci_ids[] = {
|
|
||||||
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_VLV_PMC) },
|
|
||||||
+ { 0, },
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+MODULE_DEVICE_TABLE(pci, pmc_pci_ids);
|
|
||||||
+
|
|
||||||
+static struct pci_driver pmc_pci_driver = {
|
|
||||||
+ .name = DRIVER_NAME,
|
|
||||||
+ .probe = pmc_probe,
|
|
||||||
+ .id_table = pmc_pci_ids,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+module_pci_driver(pmc_pci_driver);
|
|
||||||
+
|
|
||||||
+MODULE_AUTHOR("Aubrey Li <aubrey.li@linux.intel.com>");
|
|
||||||
+MODULE_DESCRIPTION("Intel Atom SOC Power Management Controller Interface");
|
|
||||||
+MODULE_LICENSE("GPL v2");
|
|
Loading…
Reference in New Issue
Block a user