mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
Merge "pci: msm: msm_pcie_iatu_config API clean"
This commit is contained in:
commit
e38c09a5b8
2 changed files with 287 additions and 382 deletions
|
|
@ -631,13 +631,12 @@ struct msm_pcie_sid_info_t {
|
|||
|
||||
/* PCIe device info structure */
|
||||
struct msm_pcie_device_info {
|
||||
struct list_head pcidev_node;
|
||||
u32 bdf;
|
||||
struct pci_dev *dev;
|
||||
short short_bdf;
|
||||
u32 sid;
|
||||
int domain;
|
||||
struct msm_pcie_register_event *event_reg;
|
||||
bool registered;
|
||||
};
|
||||
|
||||
/* DRV IPC command type */
|
||||
|
|
@ -844,9 +843,8 @@ struct msm_pcie_dev_t {
|
|||
uint64_t l23_rdy_poll_timeout;
|
||||
bool suspending;
|
||||
ulong wake_counter;
|
||||
u32 num_active_ep;
|
||||
u32 num_ep;
|
||||
bool pending_ep_reg;
|
||||
struct list_head enum_ep_list;
|
||||
struct list_head susp_ep_list;
|
||||
u32 num_parf_testbus_sel;
|
||||
u32 phy_len;
|
||||
struct msm_pcie_phy_info_t *phy_sequence;
|
||||
|
|
@ -858,7 +856,8 @@ struct msm_pcie_dev_t {
|
|||
u32 rc_shadow[PCIE_CONF_SPACE_DW];
|
||||
bool shadow_en;
|
||||
bool bridge_found;
|
||||
struct msm_pcie_register_event *event_reg;
|
||||
struct list_head event_reg_list;
|
||||
spinlock_t evt_reg_list_lock;
|
||||
bool power_on;
|
||||
void *ipc_log;
|
||||
void *ipc_log_long;
|
||||
|
|
@ -1642,12 +1641,6 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev)
|
|||
dev->aux_clk_freq);
|
||||
PCIE_DBG_FS(dev, "user_suspend is %d\n",
|
||||
dev->user_suspend);
|
||||
PCIE_DBG_FS(dev, "num_ep: %d\n",
|
||||
dev->num_ep);
|
||||
PCIE_DBG_FS(dev, "num_active_ep: %d\n",
|
||||
dev->num_active_ep);
|
||||
PCIE_DBG_FS(dev, "pending_ep_reg: %s\n",
|
||||
dev->pending_ep_reg ? "true" : "false");
|
||||
PCIE_DBG_FS(dev, "num_parf_testbus_sel is 0x%x",
|
||||
dev->num_parf_testbus_sel);
|
||||
PCIE_DBG_FS(dev, "phy_len is %d",
|
||||
|
|
@ -2868,11 +2861,11 @@ static bool msm_pcie_check_ltssm_state(struct msm_pcie_dev_t *dev, u32 state)
|
|||
* @host_addr: - region start address on host
|
||||
* @host_end: - region end address (low 32 bit) on host,
|
||||
* upper 32 bits are same as for @host_addr
|
||||
* @target_addr: - region start address on target
|
||||
* @bdf: - bus:device:function
|
||||
*/
|
||||
static void msm_pcie_iatu_config(struct msm_pcie_dev_t *dev, int nr, u8 type,
|
||||
unsigned long host_addr, u32 host_end,
|
||||
unsigned long target_addr)
|
||||
unsigned long host_addr, u32 host_end,
|
||||
u32 bdf)
|
||||
{
|
||||
void __iomem *iatu_base = dev->iatu ? dev->iatu : dev->dm_core;
|
||||
|
||||
|
|
@ -2885,6 +2878,10 @@ static void msm_pcie_iatu_config(struct msm_pcie_dev_t *dev, int nr, u8 type,
|
|||
u32 iatu_ltar_offset;
|
||||
u32 iatu_utar_offset;
|
||||
|
||||
/* configure iATU only for endpoints */
|
||||
if (!bdf)
|
||||
return;
|
||||
|
||||
if (dev->iatu) {
|
||||
iatu_viewport_offset = 0;
|
||||
iatu_ctrl1_offset = PCIE_IATU_CTRL1(nr);
|
||||
|
|
@ -2905,25 +2902,6 @@ static void msm_pcie_iatu_config(struct msm_pcie_dev_t *dev, int nr, u8 type,
|
|||
iatu_utar_offset = PCIE20_PLR_IATU_UTAR;
|
||||
}
|
||||
|
||||
if (dev->shadow_en && iatu_viewport_offset) {
|
||||
dev->rc_shadow[PCIE20_PLR_IATU_VIEWPORT / 4] =
|
||||
nr;
|
||||
dev->rc_shadow[PCIE20_PLR_IATU_CTRL1 / 4] =
|
||||
type;
|
||||
dev->rc_shadow[PCIE20_PLR_IATU_LBAR / 4] =
|
||||
lower_32_bits(host_addr);
|
||||
dev->rc_shadow[PCIE20_PLR_IATU_UBAR / 4] =
|
||||
upper_32_bits(host_addr);
|
||||
dev->rc_shadow[PCIE20_PLR_IATU_LAR / 4] =
|
||||
host_end;
|
||||
dev->rc_shadow[PCIE20_PLR_IATU_LTAR / 4] =
|
||||
lower_32_bits(target_addr);
|
||||
dev->rc_shadow[PCIE20_PLR_IATU_UTAR / 4] =
|
||||
upper_32_bits(target_addr);
|
||||
dev->rc_shadow[PCIE20_PLR_IATU_CTRL2 / 4] =
|
||||
BIT(31);
|
||||
}
|
||||
|
||||
/* select region */
|
||||
if (iatu_viewport_offset)
|
||||
msm_pcie_write_reg(iatu_base, iatu_viewport_offset, nr);
|
||||
|
|
@ -2937,36 +2915,9 @@ static void msm_pcie_iatu_config(struct msm_pcie_dev_t *dev, int nr, u8 type,
|
|||
msm_pcie_write_reg(iatu_base, iatu_ubar_offset,
|
||||
upper_32_bits(host_addr));
|
||||
msm_pcie_write_reg(iatu_base, iatu_lar_offset, host_end);
|
||||
msm_pcie_write_reg(iatu_base, iatu_ltar_offset,
|
||||
lower_32_bits(target_addr));
|
||||
msm_pcie_write_reg(iatu_base, iatu_utar_offset,
|
||||
upper_32_bits(target_addr));
|
||||
msm_pcie_write_reg(iatu_base, iatu_ltar_offset, lower_32_bits(bdf));
|
||||
msm_pcie_write_reg(iatu_base, iatu_utar_offset, 0);
|
||||
msm_pcie_write_reg(iatu_base, iatu_ctrl2_offset, BIT(31));
|
||||
|
||||
if (dev->enumerated) {
|
||||
PCIE_DBG2(dev, "IATU for Endpoint %02x:%02x.%01x\n",
|
||||
dev->pcidev_table[nr].bdf >> 24,
|
||||
dev->pcidev_table[nr].bdf >> 19 & 0x1f,
|
||||
dev->pcidev_table[nr].bdf >> 16 & 0x07);
|
||||
if (iatu_viewport_offset)
|
||||
PCIE_DBG2(dev, "IATU_VIEWPORT:0x%x\n",
|
||||
readl_relaxed(dev->dm_core +
|
||||
PCIE20_PLR_IATU_VIEWPORT));
|
||||
PCIE_DBG2(dev, "IATU_CTRL1:0x%x\n",
|
||||
readl_relaxed(iatu_base + iatu_ctrl1_offset));
|
||||
PCIE_DBG2(dev, "IATU_LBAR:0x%x\n",
|
||||
readl_relaxed(iatu_base + iatu_lbar_offset));
|
||||
PCIE_DBG2(dev, "IATU_UBAR:0x%x\n",
|
||||
readl_relaxed(iatu_base + iatu_ubar_offset));
|
||||
PCIE_DBG2(dev, "IATU_LAR:0x%x\n",
|
||||
readl_relaxed(iatu_base + iatu_lar_offset));
|
||||
PCIE_DBG2(dev, "IATU_LTAR:0x%x\n",
|
||||
readl_relaxed(iatu_base + iatu_ltar_offset));
|
||||
PCIE_DBG2(dev, "IATU_UTAR:0x%x\n",
|
||||
readl_relaxed(iatu_base + iatu_utar_offset));
|
||||
PCIE_DBG2(dev, "IATU_CTRL2:0x%x\n\n",
|
||||
readl_relaxed(iatu_base + iatu_ctrl2_offset));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -4790,62 +4741,45 @@ static void msm_pcie_disable(struct msm_pcie_dev_t *dev)
|
|||
static int msm_pcie_config_device_table(struct pci_dev *pcidev, void *pdev)
|
||||
{
|
||||
struct msm_pcie_dev_t *pcie_dev = (struct msm_pcie_dev_t *) pdev;
|
||||
int ret = 0;
|
||||
u32 rc_idx = pcie_dev->rc_idx;
|
||||
u32 i;
|
||||
u32 bdf = 0;
|
||||
struct msm_pcie_device_info *dev_info;
|
||||
int ret;
|
||||
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCI device found: vendor-id:0x%x device-id:0x%x\n",
|
||||
pcidev->vendor, pcidev->device);
|
||||
|
||||
if (!pcidev->bus->number)
|
||||
return ret;
|
||||
if (pci_pcie_type(pcidev) == PCI_EXP_TYPE_ENDPOINT) {
|
||||
dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
|
||||
if (!dev_info)
|
||||
return -ENOMEM;
|
||||
|
||||
bdf = BDF_OFFSET(pcidev->bus->number, pcidev->devfn);
|
||||
dev_info->dev = pcidev;
|
||||
list_add_tail(&dev_info->pcidev_node, &pcie_dev->enum_ep_list);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++) {
|
||||
struct msm_pcie_device_info *dev_table_t =
|
||||
&pcie_dev->pcidev_table[i];
|
||||
|
||||
if (dev_table_t->bdf != bdf)
|
||||
continue;
|
||||
|
||||
dev_table_t->dev = pcidev;
|
||||
dev_table_t->domain = rc_idx;
|
||||
|
||||
if (pci_pcie_type(pcidev) == PCI_EXP_TYPE_ENDPOINT) {
|
||||
pcie_dev->num_ep++;
|
||||
dev_table_t->registered = false;
|
||||
/* for upstream port of a switch */
|
||||
if (pci_pcie_type(pcidev) == PCI_EXP_TYPE_UPSTREAM) {
|
||||
ret = pci_enable_device(pcidev);
|
||||
if (ret) {
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: BDF 0x%04x pci_enable_device failed\n",
|
||||
PCI_DEVID(pcidev->bus->number, pcidev->devfn));
|
||||
return ret;
|
||||
}
|
||||
pci_set_master(pcidev);
|
||||
}
|
||||
|
||||
if (pci_pcie_type(pcidev) == PCI_EXP_TYPE_UPSTREAM)
|
||||
pci_set_master(pcidev);
|
||||
|
||||
if (pcie_dev->num_ep > 1)
|
||||
pcie_dev->pending_ep_reg = true;
|
||||
|
||||
if (pcie_dev->aer_enable) {
|
||||
if (pcie_dev->aer_enable) {
|
||||
#ifdef CONFIG_PCI_QTI
|
||||
if (pci_enable_pcie_error_reporting(pcidev))
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: PCIE error reporting unavailable on %02x:%02x:%01x\n",
|
||||
pcie_dev->rc_idx, pcidev->bus->number,
|
||||
PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn));
|
||||
if (pci_enable_pcie_error_reporting(pcidev))
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: PCIE error reporting unavailable on %02x:%02x:%01x\n",
|
||||
pcie_dev->rc_idx, pcidev->bus->number,
|
||||
PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn));
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAX_DEVICE_NUM) {
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: could not find device in the table: %02x:%02x:%01x\n",
|
||||
pcie_dev->rc_idx, pcidev->bus->number,
|
||||
PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn));
|
||||
ret = -ENODEV;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msm_pcie_config_sid(struct msm_pcie_dev_t *dev)
|
||||
|
|
@ -5059,37 +4993,38 @@ EXPORT_SYMBOL(msm_pcie_enumerate);
|
|||
static void msm_pcie_notify_client(struct msm_pcie_dev_t *dev,
|
||||
enum msm_pcie_event event)
|
||||
{
|
||||
if (dev->event_reg && dev->event_reg->callback &&
|
||||
(dev->event_reg->events & event)) {
|
||||
struct msm_pcie_notify *notify = &dev->event_reg->notify;
|
||||
struct msm_pcie_notify client_notify;
|
||||
struct msm_pcie_register_event *reg_itr;
|
||||
struct msm_pcie_notify *notify;
|
||||
struct msm_pcie_notify client_notify;
|
||||
|
||||
client_notify.event = event;
|
||||
client_notify.user = dev->event_reg->user;
|
||||
client_notify.data = notify->data;
|
||||
client_notify.options = notify->options;
|
||||
PCIE_DUMP(dev, "PCIe: callback RC%d for event %d\n",
|
||||
dev->rc_idx, event);
|
||||
dev->event_reg->callback(&client_notify);
|
||||
spin_lock(&dev->evt_reg_list_lock);
|
||||
list_for_each_entry(reg_itr, &dev->event_reg_list, node) {
|
||||
if ((reg_itr->events & event) && reg_itr->callback) {
|
||||
notify = ®_itr->notify;
|
||||
client_notify.event = event;
|
||||
client_notify.user = reg_itr->user;
|
||||
client_notify.data = notify->data;
|
||||
client_notify.options = notify->options;
|
||||
PCIE_DUMP(dev, "PCIe: callback RC%d for event %d\n",
|
||||
dev->rc_idx, event);
|
||||
reg_itr->callback(&client_notify);
|
||||
|
||||
if ((dev->event_reg->options & MSM_PCIE_CONFIG_NO_RECOVERY) &&
|
||||
(event == MSM_PCIE_EVENT_LINKDOWN)) {
|
||||
dev->user_suspend = true;
|
||||
PCIE_DBG(dev,
|
||||
"PCIe: Client of RC%d will recover the link later.\n",
|
||||
dev->rc_idx);
|
||||
return;
|
||||
if ((reg_itr->options & MSM_PCIE_CONFIG_NO_RECOVERY) &&
|
||||
(event == MSM_PCIE_EVENT_LINKDOWN)) {
|
||||
dev->user_suspend = true;
|
||||
PCIE_DBG(dev,
|
||||
"PCIe: Client of RC%d will recover the link later.\n",
|
||||
dev->rc_idx);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
PCIE_DBG2(dev,
|
||||
"PCIe: Client of RC%d does not have registration for event %d\n",
|
||||
dev->rc_idx, event);
|
||||
}
|
||||
spin_unlock(&dev->evt_reg_list_lock);
|
||||
}
|
||||
|
||||
static void handle_wake_func(struct work_struct *work)
|
||||
{
|
||||
int i, ret;
|
||||
struct msm_pcie_dev_t *dev = container_of(work, struct msm_pcie_dev_t,
|
||||
handle_wake_work);
|
||||
|
||||
|
|
@ -5097,65 +5032,26 @@ static void handle_wake_func(struct work_struct *work)
|
|||
|
||||
mutex_lock(&dev->recovery_lock);
|
||||
|
||||
if (!dev->enumerated) {
|
||||
PCIE_DBG(dev,
|
||||
"PCIe: Start enumeration for RC%d upon the wake from endpoint.\n",
|
||||
dev->rc_idx);
|
||||
|
||||
ret = msm_pcie_enumerate(dev->rc_idx);
|
||||
if (ret) {
|
||||
PCIE_ERR(dev,
|
||||
"PCIe: failed to enable RC%d upon wake request from the device.\n",
|
||||
dev->rc_idx);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dev->num_ep > 1) {
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++) {
|
||||
dev->event_reg = dev->pcidev_table[i].event_reg;
|
||||
|
||||
if ((dev->link_status == MSM_PCIE_LINK_ENABLED)
|
||||
&& dev->event_reg &&
|
||||
dev->event_reg->callback &&
|
||||
(dev->event_reg->events &
|
||||
MSM_PCIE_EVENT_LINKUP)) {
|
||||
struct msm_pcie_notify *notify =
|
||||
&dev->event_reg->notify;
|
||||
notify->event = MSM_PCIE_EVENT_LINKUP;
|
||||
notify->user = dev->event_reg->user;
|
||||
PCIE_DBG(dev,
|
||||
"PCIe: Linkup callback for RC%d after enumeration is successful in wake IRQ handling\n",
|
||||
dev->rc_idx);
|
||||
dev->event_reg->callback(notify);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((dev->link_status == MSM_PCIE_LINK_ENABLED) &&
|
||||
dev->event_reg && dev->event_reg->callback &&
|
||||
(dev->event_reg->events &
|
||||
MSM_PCIE_EVENT_LINKUP)) {
|
||||
struct msm_pcie_notify *notify =
|
||||
&dev->event_reg->notify;
|
||||
notify->event = MSM_PCIE_EVENT_LINKUP;
|
||||
notify->user = dev->event_reg->user;
|
||||
PCIE_DBG(dev,
|
||||
"PCIe: Linkup callback for RC%d after enumeration is successful in wake IRQ handling\n",
|
||||
dev->rc_idx);
|
||||
dev->event_reg->callback(notify);
|
||||
} else {
|
||||
PCIE_DBG(dev,
|
||||
"PCIe: Client of RC%d does not have registration for linkup event.\n",
|
||||
dev->rc_idx);
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
} else {
|
||||
if (dev->enumerated) {
|
||||
PCIE_ERR(dev,
|
||||
"PCIe: The enumeration for RC%d has already been done.\n",
|
||||
dev->rc_idx);
|
||||
"PCIe: The enumeration for RC%d has already been done.\n",
|
||||
dev->rc_idx);
|
||||
goto out;
|
||||
}
|
||||
|
||||
PCIE_DBG(dev,
|
||||
"PCIe: Start enumeration for RC%d upon the wake from endpoint.\n",
|
||||
dev->rc_idx);
|
||||
|
||||
if (msm_pcie_enumerate(dev->rc_idx)) {
|
||||
PCIE_ERR(dev,
|
||||
"PCIe: failed to enable RC%d upon wake request from the device.\n",
|
||||
dev->rc_idx);
|
||||
goto out;
|
||||
}
|
||||
|
||||
msm_pcie_notify_client(dev, MSM_PCIE_EVENT_LINKUP);
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->recovery_lock);
|
||||
}
|
||||
|
|
@ -5314,7 +5210,6 @@ static irqreturn_t handle_wake_irq(int irq, void *data)
|
|||
{
|
||||
struct msm_pcie_dev_t *dev = data;
|
||||
unsigned long irqsave_flags;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&dev->irq_lock, irqsave_flags);
|
||||
|
||||
|
|
@ -5334,23 +5229,14 @@ static irqreturn_t handle_wake_irq(int irq, void *data)
|
|||
__pm_stay_awake(dev->ws);
|
||||
__pm_relax(dev->ws);
|
||||
|
||||
if (dev->num_ep > 1) {
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++) {
|
||||
dev->event_reg =
|
||||
dev->pcidev_table[i].event_reg;
|
||||
msm_pcie_notify_client(dev,
|
||||
MSM_PCIE_EVENT_WAKEUP);
|
||||
}
|
||||
} else {
|
||||
if (dev->drv_supported && !dev->suspending &&
|
||||
dev->link_status == MSM_PCIE_LINK_ENABLED) {
|
||||
pcie_phy_dump(dev);
|
||||
pcie_parf_dump(dev);
|
||||
pcie_dm_core_dump(dev);
|
||||
}
|
||||
|
||||
msm_pcie_notify_client(dev, MSM_PCIE_EVENT_WAKEUP);
|
||||
if (dev->drv_supported && !dev->suspending &&
|
||||
dev->link_status == MSM_PCIE_LINK_ENABLED) {
|
||||
pcie_phy_dump(dev);
|
||||
pcie_parf_dump(dev);
|
||||
pcie_dm_core_dump(dev);
|
||||
}
|
||||
|
||||
msm_pcie_notify_client(dev, MSM_PCIE_EVENT_WAKEUP);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->irq_lock, irqsave_flags);
|
||||
|
|
@ -5360,8 +5246,6 @@ static irqreturn_t handle_wake_irq(int irq, void *data)
|
|||
|
||||
static void msm_pcie_handle_linkdown(struct msm_pcie_dev_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dev->link_status == MSM_PCIE_LINK_DOWN)
|
||||
return;
|
||||
|
||||
|
|
@ -5387,16 +5271,7 @@ static void msm_pcie_handle_linkdown(struct msm_pcie_dev_t *dev)
|
|||
if (dev->linkdown_panic)
|
||||
panic("User has chosen to panic on linkdown\n");
|
||||
|
||||
if (dev->num_ep > 1) {
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++) {
|
||||
dev->event_reg =
|
||||
dev->pcidev_table[i].event_reg;
|
||||
msm_pcie_notify_client(dev,
|
||||
MSM_PCIE_EVENT_LINKDOWN);
|
||||
}
|
||||
} else {
|
||||
msm_pcie_notify_client(dev, MSM_PCIE_EVENT_LINKDOWN);
|
||||
}
|
||||
msm_pcie_notify_client(dev, MSM_PCIE_EVENT_LINKDOWN);
|
||||
}
|
||||
|
||||
static irqreturn_t handle_linkdown_irq(int irq, void *data)
|
||||
|
|
@ -6349,9 +6224,6 @@ static int msm_pcie_probe(struct platform_device *pdev)
|
|||
pcie_dev->pcidev_table[i].dev = NULL;
|
||||
pcie_dev->pcidev_table[i].short_bdf = 0;
|
||||
pcie_dev->pcidev_table[i].sid = 0;
|
||||
pcie_dev->pcidev_table[i].domain = rc_idx;
|
||||
pcie_dev->pcidev_table[i].event_reg = NULL;
|
||||
pcie_dev->pcidev_table[i].registered = true;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&pdev->dev, pcie_dev);
|
||||
|
|
@ -6476,6 +6348,7 @@ static int msm_pcie_remove(struct platform_device *pdev)
|
|||
{
|
||||
int ret = 0;
|
||||
int rc_idx;
|
||||
struct msm_pcie_device_info *dev_info;
|
||||
|
||||
mutex_lock(&pcie_drv.drv_lock);
|
||||
|
||||
|
|
@ -6495,6 +6368,18 @@ static int msm_pcie_remove(struct platform_device *pdev)
|
|||
msm_pcie_gpio_deinit(&msm_pcie_dev[rc_idx]);
|
||||
msm_pcie_release_resources(&msm_pcie_dev[rc_idx]);
|
||||
|
||||
list_for_each_entry(dev_info, &msm_pcie_dev[rc_idx].enum_ep_list,
|
||||
pcidev_node) {
|
||||
list_del(&dev_info->pcidev_node);
|
||||
kfree(dev_info);
|
||||
}
|
||||
|
||||
list_for_each_entry(dev_info, &msm_pcie_dev[rc_idx].susp_ep_list,
|
||||
pcidev_node) {
|
||||
list_del(&dev_info->pcidev_node);
|
||||
kfree(dev_info);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&pcie_drv.drv_lock);
|
||||
|
||||
|
|
@ -6923,8 +6808,6 @@ static void msm_pcie_drv_notify_client(struct pcie_drv_sta *pcie_drv,
|
|||
|
||||
for (i = 0; i < MAX_RC_NUM; i++, pcie_dev++) {
|
||||
struct msm_pcie_drv_info *drv_info = pcie_dev->drv_info;
|
||||
struct msm_pcie_register_event *event_reg =
|
||||
pcie_dev->event_reg;
|
||||
|
||||
PCIE_DBG(pcie_dev, "PCIe: RC%d: event %d received\n",
|
||||
pcie_dev->rc_idx, event);
|
||||
|
|
@ -6933,9 +6816,6 @@ static void msm_pcie_drv_notify_client(struct pcie_drv_sta *pcie_drv,
|
|||
if (!drv_info)
|
||||
continue;
|
||||
|
||||
if (!event_reg || !(event_reg->events & event))
|
||||
continue;
|
||||
|
||||
if (drv_info->ep_connected) {
|
||||
msm_pcie_notify_client(pcie_dev, event);
|
||||
if (event & MSM_PCIE_EVENT_DRV_DISCONNECT) {
|
||||
|
|
@ -7106,21 +6986,11 @@ static void msm_pcie_drv_connect_worker(struct work_struct *work)
|
|||
|
||||
for (i = 0; i < MAX_RC_NUM; i++, pcie_dev++) {
|
||||
struct msm_pcie_drv_info *drv_info = pcie_dev->drv_info;
|
||||
struct msm_pcie_register_event *event_reg =
|
||||
pcie_dev->event_reg;
|
||||
|
||||
/* does not support DRV or has not been probed yet */
|
||||
if (!drv_info || drv_info->ep_connected)
|
||||
continue;
|
||||
|
||||
/* no DRV support over a switch */
|
||||
if (pcie_dev->num_ep != 1)
|
||||
continue;
|
||||
|
||||
if (!event_reg ||
|
||||
!(event_reg->events & MSM_PCIE_EVENT_DRV_CONNECT))
|
||||
continue;
|
||||
|
||||
msm_pcie_notify_client(pcie_dev,
|
||||
MSM_PCIE_EVENT_DRV_CONNECT);
|
||||
|
||||
|
|
@ -7245,6 +7115,7 @@ static int __init pcie_init(void)
|
|||
"PCIe IPC logging %s is enable for RC%d\n",
|
||||
rc_name, i);
|
||||
spin_lock_init(&msm_pcie_dev[i].cfg_lock);
|
||||
spin_lock_init(&msm_pcie_dev[i].evt_reg_list_lock);
|
||||
msm_pcie_dev[i].cfg_access = true;
|
||||
mutex_init(&msm_pcie_dev[i].enumerate_lock);
|
||||
mutex_init(&msm_pcie_dev[i].setup_lock);
|
||||
|
|
@ -7258,6 +7129,9 @@ static int __init pcie_init(void)
|
|||
msm_pcie_drv_disable_pc);
|
||||
INIT_WORK(&msm_pcie_dev[i].drv_enable_pc_work,
|
||||
msm_pcie_drv_enable_pc);
|
||||
INIT_LIST_HEAD(&msm_pcie_dev[i].enum_ep_list);
|
||||
INIT_LIST_HEAD(&msm_pcie_dev[i].susp_ep_list);
|
||||
INIT_LIST_HEAD(&msm_pcie_dev[i].event_reg_list);
|
||||
}
|
||||
|
||||
if (i2c_add_driver(&pcie_i2c_ctrl_driver))
|
||||
|
|
@ -7877,9 +7751,10 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
{
|
||||
int ret = 0;
|
||||
struct pci_dev *dev;
|
||||
u32 rc_idx = 0;
|
||||
unsigned long flags;
|
||||
struct msm_pcie_dev_t *pcie_dev;
|
||||
struct msm_pcie_device_info *dev_info_itr, *dev_info = NULL;
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
if (!user) {
|
||||
pr_err("PCIe: endpoint device is NULL\n");
|
||||
|
|
@ -7890,10 +7765,9 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
pcie_dev = PCIE_BUS_PRIV_DATA(((struct pci_dev *)user)->bus);
|
||||
|
||||
if (pcie_dev) {
|
||||
rc_idx = pcie_dev->rc_idx;
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: pm_opt:%d;busnr:%d;options:%d\n",
|
||||
rc_idx, pm_opt, busnr, options);
|
||||
"PCIe: RC%d: pm_opt:%d;busnr:%d;options:%d\n",
|
||||
pcie_dev->rc_idx, pm_opt, busnr, options);
|
||||
} else {
|
||||
pr_err(
|
||||
"PCIe: did not find RC for pci endpoint device.\n"
|
||||
|
|
@ -7902,20 +7776,22 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
goto out;
|
||||
}
|
||||
|
||||
dev = msm_pcie_dev[rc_idx].dev;
|
||||
dev = pcie_dev->dev;
|
||||
|
||||
if (!msm_pcie_dev[rc_idx].drv_ready) {
|
||||
PCIE_ERR(&msm_pcie_dev[rc_idx],
|
||||
"RC%d has not been successfully probed yet\n",
|
||||
rc_idx);
|
||||
pcidev = (struct pci_dev *)user;
|
||||
|
||||
if (!pcie_dev->drv_ready) {
|
||||
PCIE_ERR(pcie_dev,
|
||||
"RC%d has not been successfully probed yet\n",
|
||||
pcie_dev->rc_idx);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
switch (pm_opt) {
|
||||
case MSM_PCIE_DRV_SUSPEND:
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: DRV: user requests for DRV suspend\n",
|
||||
rc_idx);
|
||||
"PCIe: RC%d: DRV: user requests for DRV suspend\n",
|
||||
pcie_dev->rc_idx);
|
||||
|
||||
/* make sure disable pc is done before enabling drv */
|
||||
flush_work(&pcie_dev->drv_disable_pc_work);
|
||||
|
|
@ -7923,51 +7799,80 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
ret = msm_pcie_drv_suspend(pcie_dev, options);
|
||||
break;
|
||||
case MSM_PCIE_SUSPEND:
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"User of RC%d requests to suspend the link\n", rc_idx);
|
||||
if (msm_pcie_dev[rc_idx].link_status != MSM_PCIE_LINK_ENABLED)
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: requested to suspend when link is not enabled:%d.\n",
|
||||
rc_idx, msm_pcie_dev[rc_idx].link_status);
|
||||
|
||||
if (!msm_pcie_dev[rc_idx].power_on) {
|
||||
PCIE_ERR(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: requested to suspend when link is powered down:%d.\n",
|
||||
rc_idx, msm_pcie_dev[rc_idx].link_status);
|
||||
break;
|
||||
}
|
||||
|
||||
if (msm_pcie_dev[rc_idx].pending_ep_reg) {
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: request to suspend the link is rejected\n",
|
||||
rc_idx);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pcie_dev->num_active_ep) {
|
||||
PCIE_DBG(pcie_dev,
|
||||
"User of RC%d requests to suspend the link\n",
|
||||
pcie_dev->rc_idx);
|
||||
if (pcie_dev->link_status != MSM_PCIE_LINK_ENABLED)
|
||||
PCIE_DBG(pcie_dev,
|
||||
"RC%d: an EP requested to suspend the link, but other EPs are still active: %d\n",
|
||||
pcie_dev->rc_idx, pcie_dev->num_active_ep);
|
||||
return ret;
|
||||
"PCIe: RC%d: requested to suspend when link is not enabled:%d.\n",
|
||||
pcie_dev->rc_idx, pcie_dev->link_status);
|
||||
|
||||
if (!pcie_dev->power_on) {
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: requested to suspend when link is powered down:%d.\n",
|
||||
pcie_dev->rc_idx, pcie_dev->link_status);
|
||||
break;
|
||||
}
|
||||
|
||||
msm_pcie_dev[rc_idx].user_suspend = true;
|
||||
mutex_lock(&pcie_dev->enumerate_lock);
|
||||
|
||||
mutex_lock(&msm_pcie_dev[rc_idx].recovery_lock);
|
||||
/*
|
||||
* Remove current user requesting for suspend from ep list and
|
||||
* add it to suspend ep list. Reject susp if list is still not
|
||||
* empty.
|
||||
*/
|
||||
list_for_each_entry(dev_info_itr, &pcie_dev->enum_ep_list,
|
||||
pcidev_node) {
|
||||
if (dev_info_itr->dev == pcidev) {
|
||||
list_del(&dev_info_itr->pcidev_node);
|
||||
dev_info = dev_info_itr;
|
||||
list_add_tail(&dev_info->pcidev_node,
|
||||
&pcie_dev->susp_ep_list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev_info)
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: ep BDF 0x%04x not in enum list\n",
|
||||
pcie_dev->rc_idx, PCI_DEVID(
|
||||
pcidev->bus->number,
|
||||
pcidev->devfn));
|
||||
|
||||
if (!list_empty(&pcie_dev->enum_ep_list)) {
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: request to suspend the link is rejected\n",
|
||||
pcie_dev->rc_idx);
|
||||
mutex_unlock(&pcie_dev->enumerate_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
pcie_dev->user_suspend = true;
|
||||
|
||||
mutex_lock(&pcie_dev->recovery_lock);
|
||||
|
||||
ret = msm_pcie_pm_suspend(dev, user, data, options);
|
||||
if (ret) {
|
||||
PCIE_ERR(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: user failed to suspend the link.\n",
|
||||
rc_idx);
|
||||
msm_pcie_dev[rc_idx].user_suspend = false;
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: user failed to suspend the link.\n",
|
||||
pcie_dev->rc_idx);
|
||||
pcie_dev->user_suspend = false;
|
||||
|
||||
if (dev_info) {
|
||||
list_del(&dev_info->pcidev_node);
|
||||
list_add_tail(&dev_info->pcidev_node,
|
||||
&pcie_dev->enum_ep_list);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&msm_pcie_dev[rc_idx].recovery_lock);
|
||||
mutex_unlock(&pcie_dev->recovery_lock);
|
||||
|
||||
mutex_unlock(&pcie_dev->enumerate_lock);
|
||||
break;
|
||||
case MSM_PCIE_RESUME:
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"User of RC%d requests to resume the link\n", rc_idx);
|
||||
PCIE_DBG(pcie_dev,
|
||||
"User of RC%d requests to resume the link\n",
|
||||
pcie_dev->rc_idx);
|
||||
|
||||
/* DRV resume */
|
||||
if (pcie_dev->link_status == MSM_PCIE_LINK_DRV) {
|
||||
|
|
@ -7975,68 +7880,97 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
break;
|
||||
}
|
||||
|
||||
if (msm_pcie_dev[rc_idx].power_on) {
|
||||
PCIE_ERR(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: requested to resume when link is already powered on. Number of active EP(s): %d\n",
|
||||
rc_idx, msm_pcie_dev[rc_idx].num_active_ep);
|
||||
/* when link was suspended and link resume is requested */
|
||||
mutex_lock(&pcie_dev->enumerate_lock);
|
||||
list_for_each_entry(dev_info_itr, &pcie_dev->susp_ep_list,
|
||||
pcidev_node) {
|
||||
if (dev_info_itr->dev == user) {
|
||||
list_del(&dev_info_itr->pcidev_node);
|
||||
dev_info = dev_info_itr;
|
||||
list_add_tail(&dev_info->pcidev_node,
|
||||
&pcie_dev->enum_ep_list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev_info) {
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: ep BDF 0x%04x not in susp list\n",
|
||||
pcie_dev->rc_idx, PCI_DEVID(
|
||||
pcidev->bus->number,
|
||||
pcidev->devfn));
|
||||
}
|
||||
mutex_unlock(&pcie_dev->enumerate_lock);
|
||||
|
||||
if (pcie_dev->power_on) {
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: requested to resume when link is already powered on.\n",
|
||||
pcie_dev->rc_idx);
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&msm_pcie_dev[rc_idx].recovery_lock);
|
||||
mutex_lock(&pcie_dev->recovery_lock);
|
||||
ret = msm_pcie_pm_resume(dev, user, data, options);
|
||||
if (ret) {
|
||||
PCIE_ERR(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: user failed to resume the link.\n",
|
||||
rc_idx);
|
||||
} else {
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: user succeeded to resume the link.\n",
|
||||
rc_idx);
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: user failed to resume the link.\n",
|
||||
pcie_dev->rc_idx);
|
||||
|
||||
msm_pcie_dev[rc_idx].user_suspend = false;
|
||||
mutex_lock(&pcie_dev->enumerate_lock);
|
||||
if (dev_info) {
|
||||
list_del(&dev_info->pcidev_node);
|
||||
list_add_tail(&dev_info->pcidev_node,
|
||||
&pcie_dev->susp_ep_list);
|
||||
}
|
||||
mutex_unlock(&pcie_dev->enumerate_lock);
|
||||
} else {
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: user succeeded to resume the link.\n",
|
||||
pcie_dev->rc_idx);
|
||||
|
||||
pcie_dev->user_suspend = false;
|
||||
}
|
||||
|
||||
mutex_unlock(&msm_pcie_dev[rc_idx].recovery_lock);
|
||||
mutex_unlock(&pcie_dev->recovery_lock);
|
||||
|
||||
break;
|
||||
case MSM_PCIE_DISABLE_PC:
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"User of RC%d requests to keep the link always alive.\n",
|
||||
rc_idx);
|
||||
spin_lock_irqsave(&msm_pcie_dev[rc_idx].cfg_lock,
|
||||
msm_pcie_dev[rc_idx].irqsave_flags);
|
||||
if (msm_pcie_dev[rc_idx].suspending) {
|
||||
PCIE_ERR(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d Link has been suspended before request\n",
|
||||
rc_idx);
|
||||
PCIE_DBG(pcie_dev,
|
||||
"User of RC%d requests to keep the link always alive.\n",
|
||||
pcie_dev->rc_idx);
|
||||
spin_lock_irqsave(&pcie_dev->cfg_lock, pcie_dev->irqsave_flags);
|
||||
if (pcie_dev->suspending) {
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d Link has been suspended before request\n",
|
||||
pcie_dev->rc_idx);
|
||||
ret = MSM_PCIE_ERROR;
|
||||
} else {
|
||||
msm_pcie_dev[rc_idx].disable_pc = true;
|
||||
pcie_dev->disable_pc = true;
|
||||
}
|
||||
spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].cfg_lock,
|
||||
msm_pcie_dev[rc_idx].irqsave_flags);
|
||||
spin_unlock_irqrestore(&pcie_dev->cfg_lock,
|
||||
pcie_dev->irqsave_flags);
|
||||
break;
|
||||
case MSM_PCIE_ENABLE_PC:
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"User of RC%d cancels the request of alive link.\n",
|
||||
rc_idx);
|
||||
spin_lock_irqsave(&msm_pcie_dev[rc_idx].cfg_lock,
|
||||
msm_pcie_dev[rc_idx].irqsave_flags);
|
||||
msm_pcie_dev[rc_idx].disable_pc = false;
|
||||
spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].cfg_lock,
|
||||
msm_pcie_dev[rc_idx].irqsave_flags);
|
||||
PCIE_DBG(pcie_dev,
|
||||
"User of RC%d cancels the request of alive link.\n",
|
||||
pcie_dev->rc_idx);
|
||||
spin_lock_irqsave(&pcie_dev->cfg_lock, pcie_dev->irqsave_flags);
|
||||
pcie_dev->disable_pc = false;
|
||||
spin_unlock_irqrestore(&pcie_dev->cfg_lock,
|
||||
pcie_dev->irqsave_flags);
|
||||
break;
|
||||
case MSM_PCIE_HANDLE_LINKDOWN:
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"User of RC%d requests handling link down.\n", rc_idx);
|
||||
spin_lock_irqsave(&msm_pcie_dev[rc_idx].irq_lock, flags);
|
||||
PCIE_DBG(pcie_dev,
|
||||
"User of RC%d requests handling link down.\n",
|
||||
pcie_dev->rc_idx);
|
||||
spin_lock_irqsave(&pcie_dev->irq_lock, flags);
|
||||
msm_pcie_handle_linkdown(pcie_dev);
|
||||
spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].irq_lock, flags);
|
||||
spin_unlock_irqrestore(&pcie_dev->irq_lock, flags);
|
||||
break;
|
||||
case MSM_PCIE_DRV_PC_CTRL:
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"User of RC%d requests handling drv pc options %u.\n",
|
||||
rc_idx, options);
|
||||
PCIE_DBG(pcie_dev,
|
||||
"User of RC%d requests handling drv pc options %u.\n",
|
||||
pcie_dev->rc_idx, options);
|
||||
|
||||
mutex_lock(&pcie_dev->drv_pc_lock);
|
||||
pcie_dev->drv_disable_pc_vote =
|
||||
|
|
@ -8058,9 +7992,9 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
mutex_unlock(&pcie_dev->drv_pc_lock);
|
||||
break;
|
||||
default:
|
||||
PCIE_ERR(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: unsupported pm operation:%d.\n",
|
||||
rc_idx, pm_opt);
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: unsupported pm operation:%d.\n",
|
||||
pcie_dev->rc_idx, pm_opt);
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -8088,8 +8022,10 @@ EXPORT_SYMBOL(msm_pcie_l1ss_timeout_enable);
|
|||
|
||||
int msm_pcie_register_event(struct msm_pcie_register_event *reg)
|
||||
{
|
||||
int i, ret = 0;
|
||||
int ret = 0;
|
||||
struct msm_pcie_dev_t *pcie_dev;
|
||||
struct msm_pcie_register_event *reg_itr;
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
if (!reg) {
|
||||
pr_err("PCIe: Event registration is NULL\n");
|
||||
|
|
@ -8104,56 +8040,28 @@ int msm_pcie_register_event(struct msm_pcie_register_event *reg)
|
|||
pcie_dev = PCIE_BUS_PRIV_DATA(((struct pci_dev *)reg->user)->bus);
|
||||
|
||||
if (!pcie_dev) {
|
||||
PCIE_ERR(pcie_dev, "%s",
|
||||
"PCIe: did not find RC for pci endpoint device.\n");
|
||||
pr_err("PCIe: did not find RC for pci endpoint device.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (pcie_dev->num_ep > 1) {
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++) {
|
||||
if (reg->user ==
|
||||
pcie_dev->pcidev_table[i].dev) {
|
||||
pcie_dev->event_reg =
|
||||
pcie_dev->pcidev_table[i].event_reg;
|
||||
pcidev = (struct pci_dev *)reg->user;
|
||||
|
||||
if (!pcie_dev->event_reg) {
|
||||
pcie_dev->pcidev_table[i].registered =
|
||||
true;
|
||||
|
||||
pcie_dev->num_active_ep++;
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: number of active EP(s): %d.\n",
|
||||
pcie_dev->rc_idx,
|
||||
pcie_dev->num_active_ep);
|
||||
}
|
||||
|
||||
pcie_dev->event_reg = reg;
|
||||
pcie_dev->pcidev_table[i].event_reg = reg;
|
||||
PCIE_DBG(pcie_dev,
|
||||
"Event 0x%x is registered for RC %d\n",
|
||||
reg->events,
|
||||
pcie_dev->rc_idx);
|
||||
|
||||
break;
|
||||
}
|
||||
spin_lock(&pcie_dev->evt_reg_list_lock);
|
||||
list_for_each_entry(reg_itr, &pcie_dev->event_reg_list, node) {
|
||||
if (reg_itr->user == reg->user) {
|
||||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: EP BDF 0x%4x already registered\n",
|
||||
pcie_dev->rc_idx,
|
||||
PCI_DEVID(pcidev->bus->number, pcidev->devfn));
|
||||
spin_unlock(&pcie_dev->evt_reg_list_lock);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
if (pcie_dev->pending_ep_reg) {
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++)
|
||||
if (!pcie_dev->pcidev_table[i].registered)
|
||||
break;
|
||||
|
||||
if (i == MAX_DEVICE_NUM)
|
||||
pcie_dev->pending_ep_reg = false;
|
||||
}
|
||||
} else {
|
||||
pcie_dev->event_reg = reg;
|
||||
PCIE_DBG(pcie_dev,
|
||||
"Event 0x%x is registered for RC %d\n", reg->events,
|
||||
pcie_dev->rc_idx);
|
||||
|
||||
schedule_work(&pcie_drv.drv_connect);
|
||||
}
|
||||
list_add_tail(®->node, &pcie_dev->event_reg_list);
|
||||
spin_unlock(&pcie_dev->evt_reg_list_lock);
|
||||
|
||||
if (pcie_dev->drv_supported)
|
||||
schedule_work(&pcie_drv.drv_connect);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -8161,8 +8069,9 @@ EXPORT_SYMBOL(msm_pcie_register_event);
|
|||
|
||||
int msm_pcie_deregister_event(struct msm_pcie_register_event *reg)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct msm_pcie_dev_t *pcie_dev;
|
||||
struct pci_dev *pcidev;
|
||||
struct msm_pcie_register_event *reg_itr;
|
||||
|
||||
if (!reg) {
|
||||
pr_err("PCIe: Event deregistration is NULL\n");
|
||||
|
|
@ -8182,33 +8091,28 @@ int msm_pcie_deregister_event(struct msm_pcie_register_event *reg)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (pcie_dev->num_ep > 1) {
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++) {
|
||||
if (reg->user == pcie_dev->pcidev_table[i].dev) {
|
||||
if (pcie_dev->pcidev_table[i].event_reg) {
|
||||
pcie_dev->num_active_ep--;
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: number of active EP(s) left: %d.\n",
|
||||
pcie_dev->rc_idx,
|
||||
pcie_dev->num_active_ep);
|
||||
}
|
||||
pcidev = (struct pci_dev *)reg->user;
|
||||
|
||||
pcie_dev->event_reg = NULL;
|
||||
pcie_dev->pcidev_table[i].event_reg = NULL;
|
||||
PCIE_DBG(pcie_dev,
|
||||
"Event is deregistered for RC %d\n",
|
||||
pcie_dev->rc_idx);
|
||||
|
||||
break;
|
||||
}
|
||||
spin_lock(&pcie_dev->evt_reg_list_lock);
|
||||
list_for_each_entry(reg_itr, &pcie_dev->event_reg_list, node) {
|
||||
if (reg_itr->user == reg->user) {
|
||||
list_del(®->node);
|
||||
spin_unlock(&pcie_dev->evt_reg_list_lock);
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: Event deregistered for BDF 0x%04x\n",
|
||||
pcie_dev->rc_idx,
|
||||
PCI_DEVID(pcidev->bus->number, pcidev->devfn));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
pcie_dev->event_reg = NULL;
|
||||
PCIE_DBG(pcie_dev, "Event is deregistered for RC %d\n",
|
||||
pcie_dev->rc_idx);
|
||||
}
|
||||
spin_unlock(&pcie_dev->evt_reg_list_lock);
|
||||
|
||||
return ret;
|
||||
PCIE_DBG(pcie_dev,
|
||||
"PCIe: RC%d: Failed to deregister event for BDF 0x%04x\n",
|
||||
pcie_dev->rc_idx,
|
||||
PCI_DEVID(pcidev->bus->number, pcidev->devfn));
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(msm_pcie_deregister_event);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ struct msm_pcie_notify {
|
|||
};
|
||||
|
||||
struct msm_pcie_register_event {
|
||||
struct list_head node;
|
||||
u32 events;
|
||||
void *user;
|
||||
enum msm_pcie_trigger mode;
|
||||
|
|
|
|||
Loading…
Reference in a new issue