* Re: [PATCH net-next v3 1/2] net: phy: replace PHY_HAS_INTERRUPT with a check for config_intr and ack_interrupt
From: Martin Blumenstingl @ 2018-11-12 20:32 UTC (permalink / raw)
To: hkallweit1
Cc: f.fainelli, andrew, netdev, richardcochran, linux-kernel,
bcm-kernel-feedback-list, khilman, carlo, linux-amlogic, davem,
linux-arm-kernel
In-Reply-To: <c067d321-c69e-706d-304a-04e1e477b47c@gmail.com>
Hi Heiner,
On Fri, Nov 9, 2018 at 9:56 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
>
> On 09.11.2018 21:33, Florian Fainelli wrote:
> > On 11/9/18 12:22 PM, Heiner Kallweit wrote:
> >> On 09.11.2018 21:13, Andrew Lunn wrote:
> >>> Hi Heiner
> >>>
> >>>> +static bool phy_drv_supports_irq(struct phy_driver *phydrv)
> >>>> +{
> >>>> + return phydrv->config_intr || phydrv->ack_interrupt;
> >>>> +}
> >>>
> >>> Should this be && not || ? I thought both needed to be provided for
> >>> interrupts to work.
> >>>
> >>> Andrew
> >>>
> >> I've seen at least one driver which configures interrupts in
> >> config_init and doesn't define a config_intr callback
> >> (ack_interrupt callback is there)
> >
> > That driver should probably be fixed, while it most likely does not make
> > any significant difference during probe/connect, since config_init() and
> > config_intr() are virtually happening at the same time, this is not
> > necessarily true when disconnecting from the PHY where we really want
> > config_intr() to effectively disable the interrupts and not leaving
> > something enabled that would now become unmaskable, because no more
> > driver attached.
> >
> Found the driver: It's the IP101A/G in icplus.c
> It should be easy to fix the behavior and move the interrupt config
> to a config_intr callback. But the last real changes to the driver
> have been done 6 years ago, so I'm not sure there's anybody out
> there who can test.
if you want I can take care of the IP101A/G code.
I have at least one board with an IP101A/G (PHY ID: 0x02430c54,
according to the schematics it's an IP101GR-GP) where the interrupt is
routed to the SoC.
please let me know whether you'd like to work on it or if I should
give it a try.
Regards
Martin
^ permalink raw reply
* Re: [PATCH net-next v3 1/2] net: phy: replace PHY_HAS_INTERRUPT with a check for config_intr and ack_interrupt
From: Heiner Kallweit @ 2018-11-12 20:38 UTC (permalink / raw)
To: Martin Blumenstingl
Cc: f.fainelli, andrew, netdev, richardcochran, linux-kernel,
bcm-kernel-feedback-list, khilman, carlo, linux-amlogic, davem,
linux-arm-kernel
In-Reply-To: <CAFBinCCmNYGp8kzy45ojjr27tEaPVs-QwMsLRrfXHCvw_taDOw@mail.gmail.com>
On 12.11.2018 21:32, Martin Blumenstingl wrote:
> Hi Heiner,
>
> On Fri, Nov 9, 2018 at 9:56 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
>>
>> On 09.11.2018 21:33, Florian Fainelli wrote:
>>> On 11/9/18 12:22 PM, Heiner Kallweit wrote:
>>>> On 09.11.2018 21:13, Andrew Lunn wrote:
>>>>> Hi Heiner
>>>>>
>>>>>> +static bool phy_drv_supports_irq(struct phy_driver *phydrv)
>>>>>> +{
>>>>>> + return phydrv->config_intr || phydrv->ack_interrupt;
>>>>>> +}
>>>>>
>>>>> Should this be && not || ? I thought both needed to be provided for
>>>>> interrupts to work.
>>>>>
>>>>> Andrew
>>>>>
>>>> I've seen at least one driver which configures interrupts in
>>>> config_init and doesn't define a config_intr callback
>>>> (ack_interrupt callback is there)
>>>
>>> That driver should probably be fixed, while it most likely does not make
>>> any significant difference during probe/connect, since config_init() and
>>> config_intr() are virtually happening at the same time, this is not
>>> necessarily true when disconnecting from the PHY where we really want
>>> config_intr() to effectively disable the interrupts and not leaving
>>> something enabled that would now become unmaskable, because no more
>>> driver attached.
>>>
>> Found the driver: It's the IP101A/G in icplus.c
>> It should be easy to fix the behavior and move the interrupt config
>> to a config_intr callback. But the last real changes to the driver
>> have been done 6 years ago, so I'm not sure there's anybody out
>> there who can test.
> if you want I can take care of the IP101A/G code.
> I have at least one board with an IP101A/G (PHY ID: 0x02430c54,
> according to the schematics it's an IP101GR-GP) where the interrupt is
> routed to the SoC.
>
> please let me know whether you'd like to work on it or if I should
> give it a try.
>
I made the change already based on the datasheet of IP101A LF which
is supposed to be register-compatible with IP101A/G.
The patch is not applied yet, you can find it in the mailing
list archive or in patchwork. Would be great if you could test it
and report problems or add a Tested-by.
>
> Regards
> Martin
>
Rgds, Heiner
^ permalink raw reply
* [PATCH net v2 0/4] qed: Miscellaneous bug fixes
From: Denis Bolotin @ 2018-11-12 10:50 UTC (permalink / raw)
To: davem, netdev; +Cc: michal.kalderon, ariel.elior, Denis Bolotin
Hi Dave,
This patch series fixes several unrelated bugs across the driver.
Please consider applying to net.
V1->V2:
-------
Use dma_rmb() instead of rmb().
Thanks,
Denis
Denis Bolotin (3):
qed: Fix PTT leak in qed_drain()
qed: Fix overriding offload_tc by protocols without APP TLV
qed: Fix reading wrong value in loop condition
Michal Kalderon (1):
qed: Fix rdma_info structure allocation
drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 14 ++++-----
drivers/net/ethernet/qlogic/qed/qed_dev.c | 15 ++++++---
drivers/net/ethernet/qlogic/qed/qed_int.c | 2 ++
drivers/net/ethernet/qlogic/qed/qed_main.c | 2 +-
drivers/net/ethernet/qlogic/qed/qed_rdma.c | 50 +++++++++++++++++-------------
drivers/net/ethernet/qlogic/qed/qed_rdma.h | 5 +++
6 files changed, 55 insertions(+), 33 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH net v2 1/4] qed: Fix PTT leak in qed_drain()
From: Denis Bolotin @ 2018-11-12 10:50 UTC (permalink / raw)
To: davem, netdev; +Cc: michal.kalderon, ariel.elior, Denis Bolotin
In-Reply-To: <20181112105023.23842-1-denis.bolotin@cavium.com>
Release PTT before entering error flow.
Signed-off-by: Denis Bolotin <denis.bolotin@cavium.com>
Signed-off-by: Michal Kalderon <michal.kalderon@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 35fd0db..fff7f04 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1782,9 +1782,9 @@ static int qed_drain(struct qed_dev *cdev)
return -EBUSY;
}
rc = qed_mcp_drain(hwfn, ptt);
+ qed_ptt_release(hwfn, ptt);
if (rc)
return rc;
- qed_ptt_release(hwfn, ptt);
}
return 0;
--
1.8.3.1
^ permalink raw reply related
* [PATCH net v2 4/4] qed: Fix reading wrong value in loop condition
From: Denis Bolotin @ 2018-11-12 10:50 UTC (permalink / raw)
To: davem, netdev; +Cc: michal.kalderon, ariel.elior, Denis Bolotin
In-Reply-To: <20181112105023.23842-1-denis.bolotin@cavium.com>
The value of "sb_index" is written by the hardware. Reading its value and
writing it to "index" must finish before checking the loop condition.
Signed-off-by: Denis Bolotin <denis.bolotin@cavium.com>
Signed-off-by: Michal Kalderon <michal.kalderon@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_int.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c
index 0f0aba7..b22f464 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -992,6 +992,8 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn)
*/
do {
index = p_sb_attn->sb_index;
+ /* finish reading index before the loop condition */
+ dma_rmb();
attn_bits = le32_to_cpu(p_sb_attn->atten_bits);
attn_acks = le32_to_cpu(p_sb_attn->atten_ack);
} while (index != p_sb_attn->sb_index);
--
1.8.3.1
^ permalink raw reply related
* [PATCH net v2 3/4] qed: Fix rdma_info structure allocation
From: Denis Bolotin @ 2018-11-12 10:50 UTC (permalink / raw)
To: davem, netdev; +Cc: michal.kalderon, ariel.elior, Denis Bolotin
In-Reply-To: <20181112105023.23842-1-denis.bolotin@cavium.com>
From: Michal Kalderon <michal.kalderon@cavium.com>
Certain flows need to access the rdma-info structure, for example dcbx
update flows. In some cases there can be a race between the allocation or
deallocation of the structure which was done in roce start / roce stop and
an asynchrounous dcbx event that tries to access the structure.
For this reason, we move the allocation of the rdma_info structure to be
similar to the iscsi/fcoe info structures which are allocated during device
setup.
We add a new field of "active" to the struct to define whether roce has
already been started or not, and this is checked instead of whether the
pointer to the info structure.
Fixes: 51ff17251c9c ("qed: Add support for RoCE hw init")
Signed-off-by: Michal Kalderon <michal.kalderon@cavium.com>
Signed-off-by: Denis Bolotin <denis.bolotin@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_dev.c | 15 ++++++---
drivers/net/ethernet/qlogic/qed/qed_rdma.c | 50 +++++++++++++++++-------------
drivers/net/ethernet/qlogic/qed/qed_rdma.h | 5 +++
3 files changed, 45 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index 7ceb2b9..cff1410 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -185,6 +185,10 @@ void qed_resc_free(struct qed_dev *cdev)
qed_iscsi_free(p_hwfn);
qed_ooo_free(p_hwfn);
}
+
+ if (QED_IS_RDMA_PERSONALITY(p_hwfn))
+ qed_rdma_info_free(p_hwfn);
+
qed_iov_free(p_hwfn);
qed_l2_free(p_hwfn);
qed_dmae_info_free(p_hwfn);
@@ -1081,6 +1085,12 @@ int qed_resc_alloc(struct qed_dev *cdev)
goto alloc_err;
}
+ if (QED_IS_RDMA_PERSONALITY(p_hwfn)) {
+ rc = qed_rdma_info_alloc(p_hwfn);
+ if (rc)
+ goto alloc_err;
+ }
+
/* DMA info initialization */
rc = qed_dmae_info_alloc(p_hwfn);
if (rc)
@@ -2102,11 +2112,8 @@ int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn)
if (!p_ptt)
return -EAGAIN;
- /* If roce info is allocated it means roce is initialized and should
- * be enabled in searcher.
- */
if (p_hwfn->p_rdma_info &&
- p_hwfn->b_rdma_enabled_in_prs)
+ p_hwfn->p_rdma_info->active && p_hwfn->b_rdma_enabled_in_prs)
qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0x1);
/* Re-open incoming traffic */
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
index 6211343..7873d6df 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c
@@ -140,22 +140,34 @@ static u32 qed_rdma_get_sb_id(void *p_hwfn, u32 rel_sb_id)
return FEAT_NUM((struct qed_hwfn *)p_hwfn, QED_PF_L2_QUE) + rel_sb_id;
}
-static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
- struct qed_ptt *p_ptt,
- struct qed_rdma_start_in_params *params)
+int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn)
{
struct qed_rdma_info *p_rdma_info;
- u32 num_cons, num_tasks;
- int rc = -ENOMEM;
- DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n");
-
- /* Allocate a struct with current pf rdma info */
p_rdma_info = kzalloc(sizeof(*p_rdma_info), GFP_KERNEL);
if (!p_rdma_info)
- return rc;
+ return -ENOMEM;
+
+ spin_lock_init(&p_rdma_info->lock);
p_hwfn->p_rdma_info = p_rdma_info;
+ return 0;
+}
+
+void qed_rdma_info_free(struct qed_hwfn *p_hwfn)
+{
+ kfree(p_hwfn->p_rdma_info);
+ p_hwfn->p_rdma_info = NULL;
+}
+
+static int qed_rdma_alloc(struct qed_hwfn *p_hwfn)
+{
+ struct qed_rdma_info *p_rdma_info = p_hwfn->p_rdma_info;
+ u32 num_cons, num_tasks;
+ int rc = -ENOMEM;
+
+ DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n");
+
if (QED_IS_IWARP_PERSONALITY(p_hwfn))
p_rdma_info->proto = PROTOCOLID_IWARP;
else
@@ -183,7 +195,7 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
/* Allocate a struct with device params and fill it */
p_rdma_info->dev = kzalloc(sizeof(*p_rdma_info->dev), GFP_KERNEL);
if (!p_rdma_info->dev)
- goto free_rdma_info;
+ return rc;
/* Allocate a struct with port params and fill it */
p_rdma_info->port = kzalloc(sizeof(*p_rdma_info->port), GFP_KERNEL);
@@ -298,8 +310,6 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
kfree(p_rdma_info->port);
free_rdma_dev:
kfree(p_rdma_info->dev);
-free_rdma_info:
- kfree(p_rdma_info);
return rc;
}
@@ -370,8 +380,6 @@ static void qed_rdma_resc_free(struct qed_hwfn *p_hwfn)
kfree(p_rdma_info->port);
kfree(p_rdma_info->dev);
-
- kfree(p_rdma_info);
}
static void qed_rdma_free_tid(void *rdma_cxt, u32 itid)
@@ -679,8 +687,6 @@ static int qed_rdma_setup(struct qed_hwfn *p_hwfn,
DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA setup\n");
- spin_lock_init(&p_hwfn->p_rdma_info->lock);
-
qed_rdma_init_devinfo(p_hwfn, params);
qed_rdma_init_port(p_hwfn);
qed_rdma_init_events(p_hwfn, params);
@@ -727,7 +733,7 @@ static int qed_rdma_stop(void *rdma_cxt)
/* Disable RoCE search */
qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0);
p_hwfn->b_rdma_enabled_in_prs = false;
-
+ p_hwfn->p_rdma_info->active = 0;
qed_wr(p_hwfn, p_ptt, PRS_REG_ROCE_DEST_QP_MAX_PF, 0);
ll2_ethertype_en = qed_rd(p_hwfn, p_ptt, PRS_REG_LIGHT_L2_ETHERTYPE_EN);
@@ -1236,7 +1242,8 @@ static int qed_rdma_destroy_qp(void *rdma_cxt, struct qed_rdma_qp *qp)
u8 max_stats_queues;
int rc;
- if (!rdma_cxt || !in_params || !out_params || !p_hwfn->p_rdma_info) {
+ if (!rdma_cxt || !in_params || !out_params ||
+ !p_hwfn->p_rdma_info->active) {
DP_ERR(p_hwfn->cdev,
"qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n",
rdma_cxt, in_params, out_params);
@@ -1802,8 +1809,8 @@ bool qed_rdma_allocated_qps(struct qed_hwfn *p_hwfn)
{
bool result;
- /* if rdma info has not been allocated, naturally there are no qps */
- if (!p_hwfn->p_rdma_info)
+ /* if rdma wasn't activated yet, naturally there are no qps */
+ if (!p_hwfn->p_rdma_info->active)
return false;
spin_lock_bh(&p_hwfn->p_rdma_info->lock);
@@ -1849,7 +1856,7 @@ static int qed_rdma_start(void *rdma_cxt,
if (!p_ptt)
goto err;
- rc = qed_rdma_alloc(p_hwfn, p_ptt, params);
+ rc = qed_rdma_alloc(p_hwfn);
if (rc)
goto err1;
@@ -1858,6 +1865,7 @@ static int qed_rdma_start(void *rdma_cxt,
goto err2;
qed_ptt_release(p_hwfn, p_ptt);
+ p_hwfn->p_rdma_info->active = 1;
return rc;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.h b/drivers/net/ethernet/qlogic/qed/qed_rdma.h
index 6f722ee..50d609c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_rdma.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.h
@@ -102,6 +102,7 @@ struct qed_rdma_info {
u16 max_queue_zones;
enum protocol_type proto;
struct qed_iwarp_info iwarp;
+ u8 active:1;
};
struct qed_rdma_qp {
@@ -176,10 +177,14 @@ struct qed_rdma_qp {
#if IS_ENABLED(CONFIG_QED_RDMA)
void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
+int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn);
+void qed_rdma_info_free(struct qed_hwfn *p_hwfn);
#else
static inline void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) {}
static inline void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt) {}
+static inline int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn) {return -EINVAL}
+static inline void qed_rdma_info_free(struct qed_hwfn *p_hwfn) {}
#endif
int
--
1.8.3.1
^ permalink raw reply related
* [PATCH net v2 2/4] qed: Fix overriding offload_tc by protocols without APP TLV
From: Denis Bolotin @ 2018-11-12 10:50 UTC (permalink / raw)
To: davem, netdev; +Cc: michal.kalderon, ariel.elior, Denis Bolotin
In-Reply-To: <20181112105023.23842-1-denis.bolotin@cavium.com>
The TC received from APP TLV is stored in offload_tc, and should not be
set by protocols which did not receive an APP TLV. Fixed the condition
when overriding the offload_tc.
Signed-off-by: Denis Bolotin <denis.bolotin@cavium.com>
Signed-off-by: Michal Kalderon <michal.kalderon@cavium.com>
---
drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
index 8e8fa82..69966df 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c
@@ -191,7 +191,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
static void
qed_dcbx_set_params(struct qed_dcbx_results *p_data,
struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
- bool enable, u8 prio, u8 tc,
+ bool app_tlv, bool enable, u8 prio, u8 tc,
enum dcbx_protocol_type type,
enum qed_pci_personality personality)
{
@@ -210,7 +210,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
p_data->arr[type].dont_add_vlan0 = true;
/* QM reconf data */
- if (p_hwfn->hw_info.personality == personality)
+ if (app_tlv && p_hwfn->hw_info.personality == personality)
qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc);
/* Configure dcbx vlan priority in doorbell block for roce EDPM */
@@ -225,7 +225,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
static void
qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
- bool enable, u8 prio, u8 tc,
+ bool app_tlv, bool enable, u8 prio, u8 tc,
enum dcbx_protocol_type type)
{
enum qed_pci_personality personality;
@@ -240,7 +240,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
personality = qed_dcbx_app_update[i].personality;
- qed_dcbx_set_params(p_data, p_hwfn, p_ptt, enable,
+ qed_dcbx_set_params(p_data, p_hwfn, p_ptt, app_tlv, enable,
prio, tc, type, personality);
}
}
@@ -319,8 +319,8 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
enable = true;
}
- qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable,
- priority, tc, type);
+ qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, true,
+ enable, priority, tc, type);
}
}
@@ -341,7 +341,7 @@ static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
continue;
enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
- qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable,
+ qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, false, enable,
priority, tc, type);
}
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] Bluetooth: Fix locking in bt_accept_enqueue() for BH context
From: Matthias Kaehlcke @ 2018-11-12 21:40 UTC (permalink / raw)
To: Marcel Holtmann, Johan Hedberg, David S . Miller, Dean Jenkins
Cc: linux-bluetooth, netdev, linux-kernel, Konstantin Khlebnikov,
Balakrishna Godavarthi, Douglas Anderson, Dmitry Grinberg
In-Reply-To: <20181015223910.197729-1-mka@chromium.org>
On Mon, Oct 15, 2018 at 03:39:10PM -0700, Matthias Kaehlcke wrote:
> With commit e16337622016 ("Bluetooth: Handle bt_accept_enqueue() socket
> atomically") lock_sock[_nested]() is used to acquire the socket lock
> before manipulating the socket. lock_sock[_nested]() may block, which
> is problematic since bt_accept_enqueue() can be called in bottom half
> context (e.g. from rfcomm_connect_ind()).
>
> The socket API provides bh_lock_sock[_nested]() to acquire the socket
> lock in bottom half context. Check the context in bt_accept_enqueue()
> and use the appropriate locking mechanism for the context.
>
> Fixes: e16337622016 ("Bluetooth: Handle bt_accept_enqueue() socket atomically")
> Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
> ---
> Not sure if this is the correct solution, it's certainly not elegant and
> checkpatch.pl complains that in_atomic() shouldn't be used outside of
> core kernel code. I'm open to other suggestions :)
>
> net/bluetooth/af_bluetooth.c | 14 ++++++++++++--
> 1 file changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
> index deacc52d7ff1..0f0540dbb44a 100644
> --- a/net/bluetooth/af_bluetooth.c
> +++ b/net/bluetooth/af_bluetooth.c
> @@ -159,10 +159,20 @@ void bt_accept_enqueue(struct sock *parent, struct sock *sk)
> BT_DBG("parent %p, sk %p", parent, sk);
>
> sock_hold(sk);
> - lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
> +
> + if (in_atomic())
> + bh_lock_sock_nested(sk);
> + else
> + lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
> +
> list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
> bt_sk(sk)->parent = parent;
> - release_sock(sk);
> +
> + if (in_atomic())
> + bh_unlock_sock(sk);
> + else
> + release_sock(sk);
> +
> parent->sk_ack_backlog++;
> }
> EXPORT_SYMBOL(bt_accept_enqueue);
Any comments or ideas for a better solutions?
Thanks
Matthias
^ permalink raw reply
* pull-request: can 2018-11-09
From: Marc Kleine-Budde @ 2018-11-12 11:57 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel
Hello David,
this is a pull request of 20 patches for net/master.
First we have a patch by Oliver Hartkopp which changes the raw socket's
raw_sendmsg() to return an error value if the user tries to send a CANFD
frame to a CAN-2.0 device.
The next two patches are by Jimmy Assarsson and fix potential problems
in the kvaser_usb driver.
YueHaibing's patches for the ucan driver fix a compile time warning and
remove a duplicate include.
Eugeniu Rosca patch adds more binding documentation to the rcar_can
driver bindings. The next two patches are by Fabrizio Castro for the
rcar_can driver and fixes a problem in the driver's probe function and
document the r8a774a1 binding.
Lukas Wunner's patch fixes a recpetion problem in hi311x driver by
switching from edge to level triggered interruts.
The next three patches all target the flexcan driver. Pankaj Bansal's
patch unconditionally unlocks the last mailbox used for RX. Alexander
Stein provides a better workaround for a hardware limitation when
sending RTR frames, by using the last mailbox for TX, resulting in fewer
lost frames. The patch by me simplyfies the driver, by making a runtime
value a compile time constant.
The following 4 patches are by me and provide the groundwork for the
next patches by Oleksij Rempel. To avoid code duplication common code in
the common CAN driver infrastructure is factured out and error handling
is cleaned up.
The next 4 patches are by Oleksij Rempel and fix the problem in the
flexcan driver that other processes see TX frames arrive out of order
with ragards to a RX'ed frame (which are send by a different system on
the CAN bus as the result of our TX frame).
regards,
Marc
---
The following changes since commit 85b18b0237ce9986a81a1b9534b5e2ee116f5504:
net: smsc95xx: Fix MTU range (2018-11-08 19:54:49 -0800)
are available in the Git repository at:
ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git tags/linux-can-fixes-for-4.20-20181109
for you to fetch changes up to d788905f68fd4714c82936f6f7f1d3644d7ae7ef:
can: flexcan: use can_rx_offload_queue_sorted() for flexcan_irq_bus_*() (2018-11-09 17:33:33 +0100)
----------------------------------------------------------------
linux-can-fixes-for-4.20-20181109
----------------------------------------------------------------
Alexander Stein (1):
can: flexcan: Always use last mailbox for TX
Eugeniu Rosca (1):
dt-bindings: can: rcar_can: document r8a77965 support
Fabrizio Castro (2):
can: rcar_can: Fix erroneous registration
dt-bindings: can: rcar_can: Add r8a774a1 support
Jimmy Assarsson (2):
can: kvaser_usb: Fix potential uninitialized variable use
can: kvaser_usb: Fix accessing freed memory in kvaser_usb_start_xmit()
Lukas Wunner (1):
can: hi311x: Use level-triggered interrupt
Marc Kleine-Budde (5):
can: flexcan: remove not needed struct flexcan_priv::tx_mb and struct flexcan_priv::tx_mb_idx
can: dev: can_get_echo_skb(): factor out non sending code to __can_get_echo_skb()
can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to access frame length
can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb is accessed out of bounds
can: dev: __can_get_echo_skb(): print error message, if trying to echo non existing skb
Oleksij Rempel (4):
can: rx-offload: introduce can_rx_offload_get_echo_skb() and can_rx_offload_queue_sorted() functions
can: flexcan: handle tx-complete CAN frames via rx-offload infrastructure
can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to can_rx_offload_queue_tail()
can: flexcan: use can_rx_offload_queue_sorted() for flexcan_irq_bus_*()
Oliver Hartkopp (1):
can: raw: check for CAN FD capable netdev in raw_sendmsg()
Pankaj Bansal (1):
can: flexcan: Unlock the MB unconditionally
YueHaibing (2):
can: ucan: remove set but not used variable 'udev'
can: ucan: remove duplicated include from ucan.c
.../devicetree/bindings/net/can/holt_hi311x.txt | 2 +-
.../devicetree/bindings/net/can/rcar_can.txt | 28 ++++--
drivers/net/can/dev.c | 48 ++++++---
drivers/net/can/flexcan.c | 108 ++++++++++++---------
drivers/net/can/rcar/rcar_can.c | 5 +-
drivers/net/can/rx-offload.c | 51 +++++++++-
drivers/net/can/spi/hi311x.c | 2 +-
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 4 +-
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 10 +-
drivers/net/can/usb/ucan.c | 7 --
include/linux/can/dev.h | 1 +
include/linux/can/rx-offload.h | 7 +-
net/can/raw.c | 15 +--
13 files changed, 190 insertions(+), 98 deletions(-)
^ permalink raw reply
* [PATCH 04/20] can: ucan: remove set but not used variable 'udev'
From: Marc Kleine-Budde @ 2018-11-12 11:57 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, YueHaibing, Marc Kleine-Budde
In-Reply-To: <20181112115728.18331-1-mkl@pengutronix.de>
From: YueHaibing <yuehaibing@huawei.com>
Fixes gcc '-Wunused-but-set-variable' warning:
drivers/net/can/usb/ucan.c: In function 'ucan_disconnect':
drivers/net/can/usb/ucan.c:1578:21: warning:
variable 'udev' set but not used [-Wunused-but-set-variable]
struct usb_device *udev;
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Reviewed-by: Martin Elshuber <martin.elshuber@theobroma-systems.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/usb/ucan.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index 0678a38b1af4..c9fd83e8d947 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -1575,11 +1575,8 @@ static int ucan_probe(struct usb_interface *intf,
/* disconnect the device */
static void ucan_disconnect(struct usb_interface *intf)
{
- struct usb_device *udev;
struct ucan_priv *up = usb_get_intfdata(intf);
- udev = interface_to_usbdev(intf);
-
usb_set_intfdata(intf, NULL);
if (up) {
--
2.19.1
^ permalink raw reply related
* [PATCH 05/20] can: ucan: remove duplicated include from ucan.c
From: Marc Kleine-Budde @ 2018-11-12 11:57 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, YueHaibing, Marc Kleine-Budde
In-Reply-To: <20181112115728.18331-1-mkl@pengutronix.de>
From: YueHaibing <yuehaibing@huawei.com>
Remove duplicated include.
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Reviewed-by: Martin Elshuber <martin.elshuber@theobroma-systems.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/usb/ucan.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index c9fd83e8d947..f3d5bda012a1 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -35,10 +35,6 @@
#include <linux/slab.h>
#include <linux/usb.h>
-#include <linux/can.h>
-#include <linux/can/dev.h>
-#include <linux/can/error.h>
-
#define UCAN_DRIVER_NAME "ucan"
#define UCAN_MAX_RX_URBS 8
/* the CAN controller needs a while to enable/disable the bus */
--
2.19.1
^ permalink raw reply related
* [PATCH 06/20] dt-bindings: can: rcar_can: document r8a77965 support
From: Marc Kleine-Budde @ 2018-11-12 11:57 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Eugeniu Rosca, Eugeniu Rosca,
Marc Kleine-Budde
In-Reply-To: <20181112115728.18331-1-mkl@pengutronix.de>
From: Eugeniu Rosca <rosca.eugeniu@gmail.com>
Document the support for rcar_can on R8A77965 SoC devices.
Add R8A77965 to the list of SoCs which require the "assigned-clocks" and
"assigned-clock-rates" properties (thanks, Sergei).
Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
Documentation/devicetree/bindings/net/can/rcar_can.txt | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt
index cc4372842bf3..47fc68148f38 100644
--- a/Documentation/devicetree/bindings/net/can/rcar_can.txt
+++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt
@@ -14,6 +14,7 @@ Required properties:
"renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC.
"renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC.
"renesas,can-r8a7796" if CAN controller is a part of R8A7796 SoC.
+ "renesas,can-r8a77965" if CAN controller is a part of R8A77965 SoC.
"renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device.
"renesas,rcar-gen2-can" for a generic R-Car Gen2 or RZ/G1
compatible device.
@@ -29,11 +30,10 @@ Required properties:
- pinctrl-0: pin control group to be used for this controller.
- pinctrl-names: must be "default".
-Required properties for "renesas,can-r8a7795" and "renesas,can-r8a7796"
-compatible:
-In R8A7795 and R8A7796 SoCs, "clkp2" can be CANFD clock. This is a div6 clock
-and can be used by both CAN and CAN FD controller at the same time. It needs to
-be scaled to maximum frequency if any of these controllers use it. This is done
+Required properties for R8A7795, R8A7796 and R8A77965:
+For the denoted SoCs, "clkp2" can be CANFD clock. This is a div6 clock and can
+be used by both CAN and CAN FD controller at the same time. It needs to be
+scaled to maximum frequency if any of these controllers use it. This is done
using the below properties:
- assigned-clocks: phandle of clkp2(CANFD) clock.
--
2.19.1
^ permalink raw reply related
* [PATCH 07/20] can: rcar_can: Fix erroneous registration
From: Marc Kleine-Budde @ 2018-11-12 11:57 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Fabrizio Castro, Chris Paterson,
Marc Kleine-Budde
In-Reply-To: <20181112115728.18331-1-mkl@pengutronix.de>
From: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Assigning 2 to "renesas,can-clock-select" tricks the driver into
registering the CAN interface, even though we don't want that.
This patch improves one of the checks to prevent that from happening.
Fixes: 862e2b6af9413b43 ("can: rcar_can: support all input clocks")
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Signed-off-by: Chris Paterson <Chris.Paterson2@renesas.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/rcar/rcar_can.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
index 11662f479e76..771a46083739 100644
--- a/drivers/net/can/rcar/rcar_can.c
+++ b/drivers/net/can/rcar/rcar_can.c
@@ -24,6 +24,9 @@
#define RCAR_CAN_DRV_NAME "rcar_can"
+#define RCAR_SUPPORTED_CLOCKS (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \
+ BIT(CLKR_CLKEXT))
+
/* Mailbox configuration:
* mailbox 60 - 63 - Rx FIFO mailboxes
* mailbox 56 - 59 - Tx FIFO mailboxes
@@ -789,7 +792,7 @@ static int rcar_can_probe(struct platform_device *pdev)
goto fail_clk;
}
- if (clock_select >= ARRAY_SIZE(clock_names)) {
+ if (!(BIT(clock_select) & RCAR_SUPPORTED_CLOCKS)) {
err = -EINVAL;
dev_err(&pdev->dev, "invalid CAN clock selected\n");
goto fail_clk;
--
2.19.1
^ permalink raw reply related
* [PATCH 08/20] dt-bindings: can: rcar_can: Add r8a774a1 support
From: Marc Kleine-Budde @ 2018-11-12 11:57 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Fabrizio Castro, Chris Paterson,
Marc Kleine-Budde
In-Reply-To: <20181112115728.18331-1-mkl@pengutronix.de>
From: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Document RZ/G2M (r8a774a1) SoC specific bindings.
Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
Signed-off-by: Chris Paterson <Chris.Paterson2@renesas.com>
Reviewed-by: Biju Das <biju.das@bp.renesas.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
.../devicetree/bindings/net/can/rcar_can.txt | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt
index 47fc68148f38..9936b9ee67c3 100644
--- a/Documentation/devicetree/bindings/net/can/rcar_can.txt
+++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt
@@ -5,6 +5,7 @@ Required properties:
- compatible: "renesas,can-r8a7743" if CAN controller is a part of R8A7743 SoC.
"renesas,can-r8a7744" if CAN controller is a part of R8A7744 SoC.
"renesas,can-r8a7745" if CAN controller is a part of R8A7745 SoC.
+ "renesas,can-r8a774a1" if CAN controller is a part of R8A774A1 SoC.
"renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC.
"renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC.
"renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC.
@@ -18,15 +19,21 @@ Required properties:
"renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device.
"renesas,rcar-gen2-can" for a generic R-Car Gen2 or RZ/G1
compatible device.
- "renesas,rcar-gen3-can" for a generic R-Car Gen3 compatible device.
+ "renesas,rcar-gen3-can" for a generic R-Car Gen3 or RZ/G2
+ compatible device.
When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first
followed by the generic version.
- reg: physical base address and size of the R-Car CAN register map.
- interrupts: interrupt specifier for the sole interrupt.
-- clocks: phandles and clock specifiers for 3 CAN clock inputs.
-- clock-names: 3 clock input name strings: "clkp1", "clkp2", "can_clk".
+- clocks: phandles and clock specifiers for 2 CAN clock inputs for RZ/G2
+ devices.
+ phandles and clock specifiers for 3 CAN clock inputs for every other
+ SoC.
+- clock-names: 2 clock input name strings for RZ/G2: "clkp1", "can_clk".
+ 3 clock input name strings for every other SoC: "clkp1", "clkp2",
+ "can_clk".
- pinctrl-0: pin control group to be used for this controller.
- pinctrl-names: must be "default".
@@ -42,8 +49,9 @@ using the below properties:
Optional properties:
- renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are:
<0x0> (default) : Peripheral clock (clkp1)
- <0x1> : Peripheral clock (clkp2)
- <0x3> : Externally input clock
+ <0x1> : Peripheral clock (clkp2) (not supported by
+ RZ/G2 devices)
+ <0x3> : External input clock
Example
-------
--
2.19.1
^ permalink raw reply related
* [PATCH 10/20] can: flexcan: Unlock the MB unconditionally
From: Marc Kleine-Budde @ 2018-11-12 11:57 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Pankaj Bansal, linux-stable,
Marc Kleine-Budde
In-Reply-To: <20181112115728.18331-1-mkl@pengutronix.de>
From: Pankaj Bansal <pankaj.bansal@nxp.com>
Unlock the MB irrespective of reception method being FIFO or timestamp
based. It is optional but recommended to unlock Mailbox as soon as
possible and make it available for reception.
Reported-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 8e972ef08637..0431f8d05518 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -720,9 +720,14 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
priv->write(BIT(n - 32), ®s->iflag2);
} else {
priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
- priv->read(®s->timer);
}
+ /* Read the Free Running Timer. It is optional but recommended
+ * to unlock Mailbox as soon as possible and make it available
+ * for reception.
+ */
+ priv->read(®s->timer);
+
return 1;
}
--
2.19.1
^ permalink raw reply related
* [PATCH 13/20] can: dev: can_get_echo_skb(): factor out non sending code to __can_get_echo_skb()
From: Marc Kleine-Budde @ 2018-11-12 11:57 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, Marc Kleine-Budde, linux-stable
In-Reply-To: <20181112115728.18331-1-mkl@pengutronix.de>
This patch factors out all non sending parts of can_get_echo_skb() into
a seperate function __can_get_echo_skb(), so that it can be re-used in
an upcoming patch.
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/dev.c | 36 +++++++++++++++++++++++++-----------
include/linux/can/dev.h | 1 +
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 49163570a63a..80530ab37b1e 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -477,14 +477,7 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
}
EXPORT_SYMBOL_GPL(can_put_echo_skb);
-/*
- * Get the skb from the stack and loop it back locally
- *
- * The function is typically called when the TX done interrupt
- * is handled in the device driver. The driver must protect
- * access to priv->echo_skb, if necessary.
- */
-unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
+struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
{
struct can_priv *priv = netdev_priv(dev);
@@ -495,13 +488,34 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
struct can_frame *cf = (struct can_frame *)skb->data;
u8 dlc = cf->can_dlc;
- netif_rx(priv->echo_skb[idx]);
+ *len_ptr = dlc;
priv->echo_skb[idx] = NULL;
- return dlc;
+ return skb;
}
- return 0;
+ return NULL;
+}
+
+/*
+ * Get the skb from the stack and loop it back locally
+ *
+ * The function is typically called when the TX done interrupt
+ * is handled in the device driver. The driver must protect
+ * access to priv->echo_skb, if necessary.
+ */
+unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
+{
+ struct sk_buff *skb;
+ u8 len;
+
+ skb = __can_get_echo_skb(dev, idx, &len);
+ if (!skb)
+ return 0;
+
+ netif_rx(skb);
+
+ return len;
}
EXPORT_SYMBOL_GPL(can_get_echo_skb);
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index a83e1f632eb7..f01623aef2f7 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -169,6 +169,7 @@ void can_change_state(struct net_device *dev, struct can_frame *cf,
void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
unsigned int idx);
+struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr);
unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
void can_free_echo_skb(struct net_device *dev, unsigned int idx);
--
2.19.1
^ permalink raw reply related
* Re: [PATCH net-next v3 1/2] net: phy: replace PHY_HAS_INTERRUPT with a check for config_intr and ack_interrupt
From: Martin Blumenstingl @ 2018-11-12 21:53 UTC (permalink / raw)
To: hkallweit1
Cc: f.fainelli, andrew, netdev, richardcochran, linux-kernel,
bcm-kernel-feedback-list, khilman, carlo, linux-amlogic, davem,
linux-arm-kernel
In-Reply-To: <b6f0c1bb-9c0b-a02a-1571-b2804fcbcaa1@gmail.com>
On Mon, Nov 12, 2018 at 9:38 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
>
> On 12.11.2018 21:32, Martin Blumenstingl wrote:
> > Hi Heiner,
> >
> > On Fri, Nov 9, 2018 at 9:56 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
> >>
> >> On 09.11.2018 21:33, Florian Fainelli wrote:
> >>> On 11/9/18 12:22 PM, Heiner Kallweit wrote:
> >>>> On 09.11.2018 21:13, Andrew Lunn wrote:
> >>>>> Hi Heiner
> >>>>>
> >>>>>> +static bool phy_drv_supports_irq(struct phy_driver *phydrv)
> >>>>>> +{
> >>>>>> + return phydrv->config_intr || phydrv->ack_interrupt;
> >>>>>> +}
> >>>>>
> >>>>> Should this be && not || ? I thought both needed to be provided for
> >>>>> interrupts to work.
> >>>>>
> >>>>> Andrew
> >>>>>
> >>>> I've seen at least one driver which configures interrupts in
> >>>> config_init and doesn't define a config_intr callback
> >>>> (ack_interrupt callback is there)
> >>>
> >>> That driver should probably be fixed, while it most likely does not make
> >>> any significant difference during probe/connect, since config_init() and
> >>> config_intr() are virtually happening at the same time, this is not
> >>> necessarily true when disconnecting from the PHY where we really want
> >>> config_intr() to effectively disable the interrupts and not leaving
> >>> something enabled that would now become unmaskable, because no more
> >>> driver attached.
> >>>
> >> Found the driver: It's the IP101A/G in icplus.c
> >> It should be easy to fix the behavior and move the interrupt config
> >> to a config_intr callback. But the last real changes to the driver
> >> have been done 6 years ago, so I'm not sure there's anybody out
> >> there who can test.
> > if you want I can take care of the IP101A/G code.
> > I have at least one board with an IP101A/G (PHY ID: 0x02430c54,
> > according to the schematics it's an IP101GR-GP) where the interrupt is
> > routed to the SoC.
> >
> > please let me know whether you'd like to work on it or if I should
> > give it a try.
> >
> I made the change already based on the datasheet of IP101A LF which
> is supposed to be register-compatible with IP101A/G.
> The patch is not applied yet, you can find it in the mailing
> list archive or in patchwork. Would be great if you could test it
> and report problems or add a Tested-by.
I will test it but I doubt it works out-of-the-box in my setup:
my board routes the RXER/INTR_32 pin of the IP101GR to the SoC. that
pin defaults to "RXER" (receive error signal). so I need to come up
with some extra patches which toggle the bit to output the interrupt
signal on that pin
in other words: I'll give your patches a try as soon as I have time
and give my Tested-by along with my extra patches on top of yours.
Regards
Martin
^ permalink raw reply
* [PATCH] bpf: Remove unused variable in nsim_bpf
From: Nathan Chancellor @ 2018-11-12 22:10 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann
Cc: Quentin Monnet, Jakub Kicinski, netdev, linux-kernel,
Nathan Chancellor
Clang warns:
drivers/net/netdevsim/bpf.c:557:30: error: unused variable 'state'
[-Werror,-Wunused-variable]
struct nsim_bpf_bound_prog *state;
^
1 error generated.
The declaration should have been removed in commit b07ade27e933 ("bpf:
pass translate() as a callback and remove its ndo_bpf subcommand").
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
drivers/net/netdevsim/bpf.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
index 6a5b7bd9a1f9..a1b29173ca1c 100644
--- a/drivers/net/netdevsim/bpf.c
+++ b/drivers/net/netdevsim/bpf.c
@@ -554,7 +554,6 @@ static void nsim_bpf_map_free(struct bpf_offloaded_map *offmap)
int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf)
{
struct netdevsim *ns = netdev_priv(dev);
- struct nsim_bpf_bound_prog *state;
int err;
ASSERT_RTNL();
--
2.19.1
^ permalink raw reply related
* [PATCH] geneve: Add missing braces in addr6 initializer
From: Nathan Chancellor @ 2018-11-12 22:12 UTC (permalink / raw)
To: David S. Miller
Cc: Stefano Brivio, Sabrina Dubroca, netdev, linux-kernel,
Nathan Chancellor
Clang warns:
drivers/net/geneve.c:428:29: error: suggest braces around initialization
of subobject [-Werror,-Wmissing-braces]
struct in6_addr addr6 = { 0 };
^
{}
Fixes: a07966447f39 ("geneve: ICMP error lookup handler")
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
drivers/net/geneve.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 7c53e06b31c3..224d8b0bb5de 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -425,7 +425,7 @@ static int geneve_udp_encap_err_lookup(struct sock *sk, struct sk_buff *skb)
#if IS_ENABLED(CONFIG_IPV6)
if (geneve_get_sk_family(gs) == AF_INET6) {
struct ipv6hdr *ip6h = ipv6_hdr(skb);
- struct in6_addr addr6 = { 0 };
+ struct in6_addr addr6 = { { 0 } };
if (!gs->collect_md) {
vni = geneve_hdr(skb)->vni;
--
2.19.1
^ permalink raw reply related
* Re: [PATCH] geneve: Add missing braces in addr6 initializer
From: Stefano Brivio @ 2018-11-12 22:19 UTC (permalink / raw)
To: Nathan Chancellor; +Cc: David S. Miller, Sabrina Dubroca, netdev, linux-kernel
In-Reply-To: <20181112221248.11477-1-natechancellor@gmail.com>
On Mon, 12 Nov 2018 15:12:48 -0700
Nathan Chancellor <natechancellor@gmail.com> wrote:
> Clang warns:
>
> drivers/net/geneve.c:428:29: error: suggest braces around initialization
> of subobject [-Werror,-Wmissing-braces]
> struct in6_addr addr6 = { 0 };
> ^
> {}
>
> Fixes: a07966447f39 ("geneve: ICMP error lookup handler")
> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
Thanks for spotting this. By the way, I guess you should indicate in
the subject when patches are meant for net-next.
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
--
Stefano
^ permalink raw reply
* Re: [PATCH] geneve: Add missing braces in addr6 initializer
From: Nathan Chancellor @ 2018-11-12 22:20 UTC (permalink / raw)
To: Stefano Brivio; +Cc: David S. Miller, Sabrina Dubroca, netdev, linux-kernel
In-Reply-To: <20181112231917.4f2f07b5@redhat.com>
On Mon, Nov 12, 2018 at 11:19:17PM +0100, Stefano Brivio wrote:
> On Mon, 12 Nov 2018 15:12:48 -0700
> Nathan Chancellor <natechancellor@gmail.com> wrote:
>
> > Clang warns:
> >
> > drivers/net/geneve.c:428:29: error: suggest braces around initialization
> > of subobject [-Werror,-Wmissing-braces]
> > struct in6_addr addr6 = { 0 };
> > ^
> > {}
> >
> > Fixes: a07966447f39 ("geneve: ICMP error lookup handler")
> > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
>
> Thanks for spotting this. By the way, I guess you should indicate in
> the subject when patches are meant for net-next.
>
Sure, I'll be better about that in the future.
> Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
>
Thank you for the review!
Nathan
> --
> Stefano
^ permalink raw reply
* RE
From: ya vila @ 2018-11-12 12:27 UTC (permalink / raw)
Mr Bayford picked you for a $1,M donation Email For more details
^ permalink raw reply
* [RFC PATCH 0/6] Armada 38x comphy driver to support 2.5Gbps networking
From: Russell King - ARM Linux @ 2018-11-12 12:29 UTC (permalink / raw)
To: devicetree, linux-arm-kernel, netdev
Cc: Andrew Lunn, Gregory Clement, Jason Cooper,
Kishon Vijay Abraham I, Mark Rutland, Rob Herring,
Sebastian Hesselbarth, Thomas Petazzoni, Maxime Chevallier
Hi,
This series adds support for dynamically switching between 1Gbps
and 2.5Gbps networking for the Marvell Armada 38x SoCs, tested on
Armada 388 on the Clearfog platform.
This is necessary to be able to connect (eg) a Clearfog platform
with a Macchiatobin platform via the SFP sockets, as Clearfog
currently only supports 1Gbps networking via the SFP socket and
Macchiatobin defaults to 2.5Gbps when using Fiberchannel SFPs.
In order to allow dynamic switching, we need to implement a common
phy driver to switch the ethernet serdes lane speed - 2.5Gbps is
just 1Gbps up-clocked by 2.5x. We implement a simple comphy
driver to achieve this, which only supports networking.
With this, we are able to support both Fiberchannel SFPs operating
at 2.5Gbps or 1Gbps, and 1G ethernet SFPs plugged into the Clearfog
platform, dynamically selecting according to the SFPs abilities.
I'm aware of the proposed changes to the PHY layer, changing
phy_set_mode() to take the ethernet phy interface type, hence why
this is RFC - there's also the question about how this will be
merged. This series is currently based on 4.20-rc1, but will
likely need to be rebased when the PHY layer changes hit.
.../bindings/net/marvell-armada-370-neta.txt | 2 +-
.../bindings/phy/phy-armada38x-comphy.txt | 40 ++++
arch/arm/boot/dts/armada-388-clearfog.dtsi | 2 +
arch/arm/boot/dts/armada-38x.dtsi | 37 ++++
drivers/net/ethernet/marvell/mvneta.c | 58 ++++-
drivers/phy/marvell/Kconfig | 10 +
drivers/phy/marvell/Makefile | 1 +
drivers/phy/marvell/phy-armada38x-comphy.c | 236 +++++++++++++++++++++
8 files changed, 378 insertions(+), 8 deletions(-)
create mode 100644 Documentation/devicetree/bindings/phy/phy-armada38x-comphy.txt
create mode 100644 drivers/phy/marvell/phy-armada38x-comphy.c
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
^ permalink raw reply
* [RFC PATCH 1/6] dt-bindings: phy: Armada 38x common phy bindings
From: Russell King @ 2018-11-12 12:30 UTC (permalink / raw)
To: devicetree, linux-arm-kernel, netdev
Cc: Andrew Lunn, Gregory Clement, Jason Cooper,
Kishon Vijay Abraham I, Mark Rutland, Rob Herring,
Sebastian Hesselbarth, Thomas Petazzoni, Maxime Chevallier
In-Reply-To: <20181112122933.GD30658@n2100.armlinux.org.uk>
Add the Marvell Armada 38x common phy bindings.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
.../bindings/phy/phy-armada38x-comphy.txt | 40 ++++++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/phy-armada38x-comphy.txt
diff --git a/Documentation/devicetree/bindings/phy/phy-armada38x-comphy.txt b/Documentation/devicetree/bindings/phy/phy-armada38x-comphy.txt
new file mode 100644
index 000000000000..ad49e5c01334
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-armada38x-comphy.txt
@@ -0,0 +1,40 @@
+mvebu armada 38x comphy driver
+------------------------------
+
+This comphy controller can be found on Marvell Armada 38x. It provides a
+number of shared PHYs used by various interfaces (network, sata, usb,
+PCIe...).
+
+Required properties:
+
+- compatible: should be "marvell,armada-380-comphy"
+- reg: should contain the comphy register location and length.
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+
+A sub-node is required for each comphy lane provided by the comphy.
+
+Required properties (child nodes):
+
+- reg: comphy lane number.
+- #phy-cells : from the generic phy bindings, must be 1. Defines the
+ input port to use for a given comphy lane.
+
+Example:
+
+ comphy: phy@18300 {
+ compatible = "marvell,armada-380-comphy";
+ reg = <0x18300 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpm_comphy0: phy@0 {
+ reg = <0>;
+ #phy-cells = <1>;
+ };
+
+ cpm_comphy1: phy@1 {
+ reg = <1>;
+ #phy-cells = <1>;
+ };
+ };
--
2.7.4
^ permalink raw reply related
* [RFC PATCH 2/6] phy: armada38x: add common phy support
From: Russell King @ 2018-11-12 12:30 UTC (permalink / raw)
To: devicetree, linux-arm-kernel, netdev
Cc: Andrew Lunn, Gregory Clement, Jason Cooper,
Kishon Vijay Abraham I, Mark Rutland, Rob Herring,
Sebastian Hesselbarth, Thomas Petazzoni, Maxime Chevallier
In-Reply-To: <20181112122933.GD30658@n2100.armlinux.org.uk>
Add support for the Armada 38x common phy to allow us to change the
speed of the Ethernet serdes lane. This driver only supports
manipulation of the speed, it does not support configuration of the
common phy.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/phy/marvell/Kconfig | 10 ++
drivers/phy/marvell/Makefile | 1 +
drivers/phy/marvell/phy-armada38x-comphy.c | 236 +++++++++++++++++++++++++++++
3 files changed, 247 insertions(+)
create mode 100644 drivers/phy/marvell/phy-armada38x-comphy.c
diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig
index 6fb4b56e4c14..224ea4e6a46d 100644
--- a/drivers/phy/marvell/Kconfig
+++ b/drivers/phy/marvell/Kconfig
@@ -21,6 +21,16 @@ config PHY_BERLIN_USB
help
Enable this to support the USB PHY on Marvell Berlin SoCs.
+config PHY_MVEBU_A38X_COMPHY
+ tristate "Marvell Armada 38x comphy driver"
+ depends on ARCH_MVEBU || COMPILE_TEST
+ depends on OF
+ select GENERIC_PHY
+ help
+ This driver allows to control the comphy, an hardware block providing
+ shared serdes PHYs on Marvell Armada 38x. Its serdes lanes can be
+ used by various controllers (Ethernet, sata, usb, PCIe...).
+
config PHY_MVEBU_CP110_COMPHY
tristate "Marvell CP110 comphy driver"
depends on ARCH_MVEBU || COMPILE_TEST
diff --git a/drivers/phy/marvell/Makefile b/drivers/phy/marvell/Makefile
index 3975b144f8ec..59b6c03ef756 100644
--- a/drivers/phy/marvell/Makefile
+++ b/drivers/phy/marvell/Makefile
@@ -2,6 +2,7 @@
obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o
+obj-$(CONFIG_PHY_MVEBU_A38X_COMPHY) += phy-armada38x-comphy.o
obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o
obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
diff --git a/drivers/phy/marvell/phy-armada38x-comphy.c b/drivers/phy/marvell/phy-armada38x-comphy.c
new file mode 100644
index 000000000000..61d1965e1cf6
--- /dev/null
+++ b/drivers/phy/marvell/phy-armada38x-comphy.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Russell King, Deep Blue Solutions Ltd.
+ *
+ * Partly derived from CP110 comphy driver by Antoine Tenart
+ * <antoine.tenart@bootlin.com>
+ */
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#define MAX_A38X_COMPHY 6
+#define MAX_A38X_PORTS 3
+
+#define COMPHY_CFG1 0x00
+#define COMPHY_CFG1_GEN_TX(x) ((x) << 26)
+#define COMPHY_CFG1_GEN_TX_MSK COMPHY_CFG1_GEN_TX(15)
+#define COMPHY_CFG1_GEN_RX(x) ((x) << 22)
+#define COMPHY_CFG1_GEN_RX_MSK COMPHY_CFG1_GEN_RX(15)
+#define GEN_SGMII_1_25GBPS 6
+#define GEN_SGMII_3_125GBPS 8
+
+#define COMPHY_STAT1 0x18
+#define COMPHY_STAT1_PLL_RDY_TX BIT(3)
+#define COMPHY_STAT1_PLL_RDY_RX BIT(2)
+
+#define COMPHY_SELECTOR 0xfc
+
+struct a38x_comphy;
+
+struct a38x_comphy_lane {
+ void __iomem *base;
+ struct a38x_comphy *priv;
+ unsigned int n;
+
+ int port;
+};
+
+struct a38x_comphy {
+ void __iomem *base;
+ struct device *dev;
+ struct a38x_comphy_lane lane[MAX_A38X_COMPHY];
+};
+
+static const u8 gbe_mux[MAX_A38X_COMPHY][MAX_A38X_PORTS] = {
+ { 0, 0, 0 },
+ { 4, 5, 0 },
+ { 0, 4, 0 },
+ { 0, 0, 4 },
+ { 0, 3, 0 },
+ { 0, 0, 3 },
+};
+
+static void a38x_comphy_set_reg(struct a38x_comphy_lane *lane,
+ unsigned int offset, u32 mask, u32 value)
+{
+ u32 val;
+
+ val = readl_relaxed(lane->base + offset) & ~mask;
+ writel(val | value, lane->base + offset);
+}
+
+static void a38x_comphy_set_speed(struct a38x_comphy_lane *lane,
+ unsigned int gen_tx, unsigned int gen_rx)
+{
+ a38x_comphy_set_reg(lane, COMPHY_CFG1,
+ COMPHY_CFG1_GEN_TX_MSK | COMPHY_CFG1_GEN_RX_MSK,
+ COMPHY_CFG1_GEN_TX(gen_tx) |
+ COMPHY_CFG1_GEN_RX(gen_rx));
+}
+
+static int a38x_comphy_poll(struct a38x_comphy_lane *lane,
+ unsigned int offset, u32 mask, u32 value)
+{
+ unsigned int timeout = 10;
+ u32 val;
+
+ while (1) {
+ val = readl_relaxed(lane->base + offset);
+ if ((val & mask) == value)
+ return 0;
+ if (!timeout--)
+ break;
+ udelay(10);
+ }
+
+ dev_err(lane->priv->dev, "comphy%u: timed out waiting for status\n",
+ lane->n);
+
+ return -ETIMEDOUT;
+}
+
+/*
+ * We only support changing the speed for comphys configured for GBE.
+ * Since that is all we do, we only poll for PLL ready status.
+ */
+static int a38x_comphy_set_mode(struct phy *phy, enum phy_mode mode)
+{
+ struct a38x_comphy_lane *lane = phy_get_drvdata(phy);
+ unsigned int gen;
+ u32 val;
+
+ val = readl_relaxed(lane->priv->base + COMPHY_SELECTOR);
+ val = (val >> (4 * lane->n)) & 0xf;
+
+ if (!gbe_mux[lane->n][lane->port] ||
+ val != gbe_mux[lane->n][lane->port]) {
+ dev_warn(lane->priv->dev,
+ "comphy%u: not configured for GBE\n", lane->n);
+ return -EINVAL;
+ }
+
+ switch (mode) {
+ case PHY_MODE_SGMII:
+ gen = GEN_SGMII_1_25GBPS;
+ break;
+
+ case PHY_MODE_2500SGMII:
+ gen = GEN_SGMII_3_125GBPS;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ a38x_comphy_set_speed(lane, gen, gen);
+
+ return a38x_comphy_poll(lane, COMPHY_STAT1,
+ COMPHY_STAT1_PLL_RDY_TX |
+ COMPHY_STAT1_PLL_RDY_RX,
+ COMPHY_STAT1_PLL_RDY_TX |
+ COMPHY_STAT1_PLL_RDY_RX);
+}
+
+static const struct phy_ops a38x_comphy_ops = {
+ .set_mode = a38x_comphy_set_mode,
+ .owner = THIS_MODULE,
+};
+
+static struct phy *a38x_comphy_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct a38x_comphy_lane *lane;
+ struct phy *phy;
+
+ if (WARN_ON(args->args[0] >= MAX_A38X_PORTS))
+ return ERR_PTR(-EINVAL);
+
+ phy = of_phy_simple_xlate(dev, args);
+ if (IS_ERR(phy))
+ return phy;
+
+ lane = phy_get_drvdata(phy);
+ if (lane->port >= 0)
+ return ERR_PTR(-EBUSY);
+
+ lane->port = args->args[0];
+
+ return phy;
+}
+
+static int a38x_comphy_probe(struct platform_device *pdev)
+{
+ struct a38x_comphy *priv;
+ struct phy_provider *provider;
+ struct device_node *child;
+ struct resource *res;
+ void __iomem *base;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ priv->dev = &pdev->dev;
+ priv->base = base;
+
+ for_each_available_child_of_node(pdev->dev.of_node, child) {
+ struct phy *phy;
+ int ret;
+ u32 val;
+
+ ret = of_property_read_u32(child, "reg", &val);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "missing 'reg' property (%d)\n",
+ ret);
+ continue;
+ }
+
+ if (val >= MAX_A38X_COMPHY || priv->lane[val].base) {
+ dev_err(&pdev->dev, "invalid 'reg' property\n");
+ continue;
+ }
+
+ phy = devm_phy_create(&pdev->dev, child, &a38x_comphy_ops);
+ if (IS_ERR(phy))
+ return PTR_ERR(phy);
+
+ priv->lane[val].base = base + 0x28 * val;
+ priv->lane[val].priv = priv;
+ priv->lane[val].n = val;
+ priv->lane[val].port = -1;
+ phy_set_drvdata(phy, &priv->lane[val]);
+ }
+
+ dev_set_drvdata(&pdev->dev, priv);
+
+ provider = devm_of_phy_provider_register(&pdev->dev, a38x_comphy_xlate);
+
+ return PTR_ERR_OR_ZERO(provider);
+}
+
+static const struct of_device_id a38x_comphy_of_match_table[] = {
+ { .compatible = "marvell,armada-380-comphy" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, a38x_comphy_of_match_table);
+
+static struct platform_driver a38x_comphy_driver = {
+ .probe = a38x_comphy_probe,
+ .driver = {
+ .name = "armada-38x-comphy",
+ .of_match_table = a38x_comphy_of_match_table,
+ },
+};
+module_platform_driver(a38x_comphy_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
+MODULE_DESCRIPTION("Common PHY driver for Armada 38x SoCs");
+MODULE_LICENSE("GPL v2");
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox