[PATCH v5 43/80] drm/vc4: hdmi: Move accessors to vc4_hdmi

2020-09-03 Thread Maxime Ripard
The current driver only supports a single HDMI controller, and part of
the issue is that the main vc4_dev structure holds a pointer to its
(only) HDMI controller, and the HDMI registers accessors will use it to
retrieve the mapped addresses.

Let's modify those accessors to use directly the vc4_hdmi structure so
that we can eventually get rid of that single global pointer.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 22 --
 drivers/gpu/drm/vc4/vc4_hdmi.h |  8 
 2 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 6733e4bc235b..81c0f67cd0eb 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -123,6 +123,7 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, 
bool force)
 {
struct drm_device *dev = connector->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
 
if (vc4->hdmi->hpd_gpio) {
if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
@@ -230,6 +231,7 @@ static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
 {
struct drm_device *dev = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
u32 packet_id = type - 0x80;
 
HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
@@ -244,6 +246,7 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder 
*encoder,
 {
struct drm_device *dev = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
u32 packet_id = frame->any.type - 0x80;
u32 packet_reg = VC4_HDMI_RAM_PACKET(packet_id);
uint8_t buffer[VC4_HDMI_PACKET_STRIDE];
@@ -623,9 +626,6 @@ static const struct drm_encoder_helper_funcs 
vc4_hdmi_encoder_helper_funcs = {
 /* HDMI audio codec callbacks */
 static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi)
 {
-   struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
-   struct drm_device *drm = encoder->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(drm);
u32 hsm_clock = clk_get_rate(vc4_hdmi->hsm_clock);
unsigned long n, m;
 
@@ -645,8 +645,6 @@ static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi)
 {
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_crtc *crtc = encoder->crtc;
-   struct drm_device *drm = encoder->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(drm);
const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
u32 samplerate = vc4_hdmi->audio.samplerate;
u32 n, cts;
@@ -683,7 +681,6 @@ static int vc4_hdmi_audio_startup(struct snd_pcm_substream 
*substream,
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
struct drm_connector *connector = &vc4_hdmi->connector.base;
-   struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
int ret;
 
if (vc4_hdmi->audio.substream && vc4_hdmi->audio.substream != substream)
@@ -714,9 +711,7 @@ static int vc4_hdmi_audio_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
 static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
 {
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
-   struct drm_device *drm = encoder->dev;
struct device *dev = &vc4_hdmi->pdev->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(drm);
int ret;
 
ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO);
@@ -747,10 +742,7 @@ static int vc4_hdmi_audio_hw_params(struct 
snd_pcm_substream *substream,
struct snd_soc_dai *dai)
 {
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
-   struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
-   struct drm_device *drm = encoder->dev;
struct device *dev = &vc4_hdmi->pdev->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(drm);
u32 audio_packet_config, channel_mask;
u32 channel_map, i;
 
@@ -821,8 +813,6 @@ static int vc4_hdmi_audio_trigger(struct snd_pcm_substream 
*substream, int cmd,
 {
struct vc4_hdmi *vc4_hdmi = dai_to_hdmi(dai);
struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
-   struct drm_device *drm = encoder->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(drm);
 
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -1082,7 +1072,8 @@ static irqreturn_t vc4_cec_irq_handler_thread(int irq, 
void *priv)
 
 static void vc4_cec_read_msg(struct vc4_dev *vc4, u32 cntrl1)
 {
-   struct cec_msg *msg = &vc4->hdmi->cec_rx_msg;
+   struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
+   struct cec_msg *msg = &vc4_hdmi->cec_rx_msg;
unsigned int i;
 
msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
@@ -112

[PATCH v5 51/80] drm/vc4: hdmi: Implement a register layout abstraction

2020-09-03 Thread Maxime Ripard
The HDMI controllers found in the BCM2711 have most of the registers
reorganized in multiple registers areas and at different offsets than
previously found.

The logic however remains pretty much the same, so it doesn't really make
sense to create a whole new driver and we should share the code as much as
possible.

Let's implement some indirection to wrap around a register and depending on
the variant will lookup the associated register on that particular variant.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c  | 427 ++---
 drivers/gpu/drm/vc4/vc4_hdmi.h  |  12 +-
 drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 241 -
 drivers/gpu/drm/vc4/vc4_regs.h  |  92 +--
 4 files changed, 464 insertions(+), 308 deletions(-)
 create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi_regs.h

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index c40050b908b5..adc7c0693650 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -50,62 +50,13 @@
 #include "media/cec.h"
 #include "vc4_drv.h"
 #include "vc4_hdmi.h"
+#include "vc4_hdmi_regs.h"
 #include "vc4_regs.h"
 
 #define HSM_CLOCK_FREQ 163682864
 #define CEC_CLOCK_FREQ 4
 #define CEC_CLOCK_DIV  (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
 
-static const struct debugfs_reg32 hdmi_regs[] = {
-   VC4_REG32(VC4_HDMI_CORE_REV),
-   VC4_REG32(VC4_HDMI_SW_RESET_CONTROL),
-   VC4_REG32(VC4_HDMI_HOTPLUG_INT),
-   VC4_REG32(VC4_HDMI_HOTPLUG),
-   VC4_REG32(VC4_HDMI_MAI_CHANNEL_MAP),
-   VC4_REG32(VC4_HDMI_MAI_CONFIG),
-   VC4_REG32(VC4_HDMI_MAI_FORMAT),
-   VC4_REG32(VC4_HDMI_AUDIO_PACKET_CONFIG),
-   VC4_REG32(VC4_HDMI_RAM_PACKET_CONFIG),
-   VC4_REG32(VC4_HDMI_HORZA),
-   VC4_REG32(VC4_HDMI_HORZB),
-   VC4_REG32(VC4_HDMI_FIFO_CTL),
-   VC4_REG32(VC4_HDMI_SCHEDULER_CONTROL),
-   VC4_REG32(VC4_HDMI_VERTA0),
-   VC4_REG32(VC4_HDMI_VERTA1),
-   VC4_REG32(VC4_HDMI_VERTB0),
-   VC4_REG32(VC4_HDMI_VERTB1),
-   VC4_REG32(VC4_HDMI_TX_PHY_RESET_CTL),
-   VC4_REG32(VC4_HDMI_TX_PHY_CTL0),
-
-   VC4_REG32(VC4_HDMI_CEC_CNTRL_1),
-   VC4_REG32(VC4_HDMI_CEC_CNTRL_2),
-   VC4_REG32(VC4_HDMI_CEC_CNTRL_3),
-   VC4_REG32(VC4_HDMI_CEC_CNTRL_4),
-   VC4_REG32(VC4_HDMI_CEC_CNTRL_5),
-   VC4_REG32(VC4_HDMI_CPU_STATUS),
-   VC4_REG32(VC4_HDMI_CPU_MASK_STATUS),
-
-   VC4_REG32(VC4_HDMI_CEC_RX_DATA_1),
-   VC4_REG32(VC4_HDMI_CEC_RX_DATA_2),
-   VC4_REG32(VC4_HDMI_CEC_RX_DATA_3),
-   VC4_REG32(VC4_HDMI_CEC_RX_DATA_4),
-   VC4_REG32(VC4_HDMI_CEC_TX_DATA_1),
-   VC4_REG32(VC4_HDMI_CEC_TX_DATA_2),
-   VC4_REG32(VC4_HDMI_CEC_TX_DATA_3),
-   VC4_REG32(VC4_HDMI_CEC_TX_DATA_4),
-};
-
-static const struct debugfs_reg32 hd_regs[] = {
-   VC4_REG32(VC4_HD_M_CTL),
-   VC4_REG32(VC4_HD_MAI_CTL),
-   VC4_REG32(VC4_HD_MAI_THR),
-   VC4_REG32(VC4_HD_MAI_FMT),
-   VC4_REG32(VC4_HD_MAI_SMP),
-   VC4_REG32(VC4_HD_VID_CTL),
-   VC4_REG32(VC4_HD_CSC_CTL),
-   VC4_REG32(VC4_HD_FRAME_COUNT),
-};
-
 static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
 {
struct drm_info_node *node = (struct drm_info_node *)m->private;
@@ -134,7 +85,7 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, 
bool force)
if (drm_probe_ddc(vc4_hdmi->ddc))
return connector_status_connected;
 
-   if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
+   if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
return connector_status_connected;
cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
return connector_status_disconnected;
@@ -223,10 +174,10 @@ static int vc4_hdmi_stop_packet(struct drm_encoder 
*encoder,
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
u32 packet_id = type - 0x80;
 
-   HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
-  HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
+   HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
+  HDMI_READ(HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
 
-   return wait_for(!(HDMI_READ(VC4_HDMI_RAM_PACKET_STATUS) &
+   return wait_for(!(HDMI_READ(HDMI_RAM_PACKET_STATUS) &
  BIT(packet_id)), 100);
 }
 
@@ -235,12 +186,16 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder 
*encoder,
 {
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
u32 packet_id = frame->any.type - 0x80;
-   u32 packet_reg = VC4_HDMI_RAM_PACKET(packet_id);
+   const struct vc4_hdmi_register *ram_packet_start =
+   &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START];
+   u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * 
packet_id;
+   void __iomem *base = __vc4_hdmi_get_field_base(vc4_hdmi,
+

[PATCH v5 36/80] dt-bindings: display: vc4: pv: Add BCM2711 pixel valves

2020-09-03 Thread Maxime Ripard
The BCM2711 comes with other pixelvalves that have different requirements
and capabilities. Let's document their compatible.

Reviewed-by: Rob Herring 
Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml | 5 
+
 1 file changed, 5 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml 
b/Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml
index e60791db1fa1..4e1ba03f6477 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-pixelvalve0.yaml
@@ -15,6 +15,11 @@ properties:
   - brcm,bcm2835-pixelvalve0
   - brcm,bcm2835-pixelvalve1
   - brcm,bcm2835-pixelvalve2
+  - brcm,bcm2711-pixelvalve0
+  - brcm,bcm2711-pixelvalve1
+  - brcm,bcm2711-pixelvalve2
+  - brcm,bcm2711-pixelvalve3
+  - brcm,bcm2711-pixelvalve4
 
   reg:
 maxItems: 1
-- 
git-series 0.9.1


[PATCH v5 38/80] drm/vc4: hdmi: Use debugfs private field

2020-09-03 Thread Maxime Ripard
We're calling vc4_debugfs_add_file with our struct vc4_hdmi pointer set
in the private field, but we don't use that field and go through the
main struct vc4_dev to get it.

Let's use the private field directly, that will save us some trouble
later on.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index ec34c08b16df..ae8c4d53e239 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -183,9 +183,7 @@ static const struct debugfs_reg32 hd_regs[] = {
 static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
 {
struct drm_info_node *node = (struct drm_info_node *)m->private;
-   struct drm_device *dev = node->minor->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(dev);
-   struct vc4_hdmi *hdmi = vc4->hdmi;
+   struct vc4_hdmi *hdmi = node->info_ent->data;
struct drm_printer p = drm_seq_file_printer(m);
 
drm_print_regset32(&p, &hdmi->hdmi_regset);
-- 
git-series 0.9.1


[PATCH v5 47/80] drm/vc4: hdmi: Retrieve the vc4_hdmi at unbind using our device

2020-09-03 Thread Maxime Ripard
The unbind function needs to retrieve a vc4_hdmi structure pointer through
the struct device that we're given since we want to support multiple HDMI
controllers.

However, our optional ASoC support doesn't make that trivial since it will
overwrite the device drvdata if we use it, but obviously won't if we don't
use it.

Let's make sure the fields are at the proper offset to be able to cast
between the snd_soc_card structure and the vc4_hdmi structure
transparently so we can support both cases.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 24 +++-
 drivers/gpu/drm/vc4/vc4_hdmi.h |  4 ++--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 44126ae55a19..e0dc823c622a 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1199,6 +1199,7 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
if (!vc4_hdmi)
return -ENOMEM;
 
+   dev_set_drvdata(dev, vc4_hdmi);
encoder = &vc4_hdmi->encoder.base.base;
vc4_hdmi->encoder.base.type = VC4_ENCODER_TYPE_HDMI0;
vc4_hdmi->pdev = pdev;
@@ -1361,7 +1362,28 @@ static void vc4_hdmi_unbind(struct device *dev, struct 
device *master,
 {
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = drm->dev_private;
-   struct vc4_hdmi *vc4_hdmi = vc4->hdmi;
+   struct vc4_hdmi *vc4_hdmi;
+
+   /*
+* ASoC makes it a bit hard to retrieve a pointer to the
+* vc4_hdmi structure. Registering the card will overwrite our
+* device drvdata with a pointer to the snd_soc_card structure,
+* which can then be used to retrieve whatever drvdata we want
+* to associate.
+*
+* However, that doesn't fly in the case where we wouldn't
+* register an ASoC card (because of an old DT that is missing
+* the dmas properties for example), then the card isn't
+* registered and the device drvdata wouldn't be set.
+*
+* We can deal with both cases by making sure a snd_soc_card
+* pointer and a vc4_hdmi structure are pointing to the same
+* memory address, so we can treat them indistinctly without any
+* issue.
+*/
+   BUILD_BUG_ON(offsetof(struct vc4_hdmi_audio, card) != 0);
+   BUILD_BUG_ON(offsetof(struct vc4_hdmi, audio) != 0);
+   vc4_hdmi = dev_get_drvdata(dev);
 
cec_unregister_adapter(vc4_hdmi->cec_adap);
vc4_hdmi_connector_destroy(&vc4_hdmi->connector.base);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 749a807cd1f3..d43462789450 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -53,13 +53,13 @@ struct vc4_hdmi_audio {
 
 /* General HDMI hardware state. */
 struct vc4_hdmi {
+   struct vc4_hdmi_audio audio;
+
struct platform_device *pdev;
 
struct vc4_hdmi_encoder encoder;
struct vc4_hdmi_connector connector;
 
-   struct vc4_hdmi_audio audio;
-
struct i2c_adapter *ddc;
void __iomem *hdmicore_regs;
void __iomem *hd_regs;
-- 
git-series 0.9.1


[PATCH v5 48/80] drm/vc4: hdmi: Remove vc4_dev hdmi pointer

2020-09-03 Thread Maxime Ripard
Now that we don't have any users anymore, we can kill that pointer.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_drv.h  | 1 -
 drivers/gpu/drm/vc4/vc4_hdmi.c | 7 ---
 2 files changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 1a97545b9244..501a48a714d3 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -73,7 +73,6 @@ struct vc4_perfmon {
 struct vc4_dev {
struct drm_device *dev;
 
-   struct vc4_hdmi *hdmi;
struct vc4_hvs *hvs;
struct vc4_v3d *v3d;
struct vc4_dpi *dpi;
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index e0dc823c622a..912560d58448 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1188,7 +1188,6 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 #endif
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
-   struct vc4_dev *vc4 = drm->dev_private;
struct vc4_hdmi *vc4_hdmi;
struct drm_encoder *encoder;
struct device_node *ddc_node;
@@ -1279,8 +1278,6 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
}
 
-   vc4->hdmi = vc4_hdmi;
-
/* HDMI core must be enabled. */
if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
@@ -1360,8 +1357,6 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 static void vc4_hdmi_unbind(struct device *dev, struct device *master,
void *data)
 {
-   struct drm_device *drm = dev_get_drvdata(master);
-   struct vc4_dev *vc4 = drm->dev_private;
struct vc4_hdmi *vc4_hdmi;
 
/*
@@ -1393,8 +1388,6 @@ static void vc4_hdmi_unbind(struct device *dev, struct 
device *master,
pm_runtime_disable(dev);
 
put_device(&vc4_hdmi->ddc->dev);
-
-   vc4->hdmi = NULL;
 }
 
 static const struct component_ops vc4_hdmi_ops = {
-- 
git-series 0.9.1


Re: [PATCH v6 09/20] gpiolib: cdev: support edge detection for uAPI v2

2020-09-03 Thread Kent Gibson
On Thu, Sep 03, 2020 at 09:55:22AM +0200, Bartosz Golaszewski wrote:
> On Mon, Aug 31, 2020 at 5:22 AM Kent Gibson  wrote:
> >
> > Add support for edge detection to lines requested using
> > GPIO_V2_GET_LINE_IOCTL.
> >
> > The edge_detector implementation is based on the v1 lineevent
> > implementation.
> >

[snip]

> > +* close in time as possible to the actual event.
> > +*/
> > +   line->timestamp = ktime_get_ns();
> > +
> > +   if (lr->num_lines != 1)
> > +   line->req_seqno = atomic_inc_return(&lr->seqno);
> 
> Do we never increase req_seqno for a single line?
> 

For a single line we just use line_seqno for both to avoid the
atomic_inc here and so reduce the time spent in the ISR and any
SMP sync overheads.

As per the comment in struct linereq:
 * @seqno: the sequence number for edge events generated on all lines in
 * this line request.  Note that this is not used when @num_lines is 1, as
 * the line_seqno is then the same and is cheaper to calculate.

Cheers,
Kent.


[PATCH v5 27/80] drm/vc4: crtc: Move HVS channel init before the PV initialisation

2020-09-03 Thread Maxime Ripard
In order to avoid stale pixels getting stuck in an intermediate FIFO
between the HVS and the pixelvalve on BCM2711, we need to configure the HVS
channel before the pixelvalve is reset and configured.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 2c5ff45dc315..b7b0e19e2fe1 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -427,10 +427,6 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 
require_hvs_enabled(dev);
 
-   vc4_crtc_config_pv(crtc);
-
-   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
-
/* Enable vblank irq handling before crtc is started otherwise
 * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist().
 */
@@ -438,6 +434,10 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 
vc4_hvs_atomic_enable(crtc, old_state);
 
+   vc4_crtc_config_pv(crtc);
+
+   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
+
/* When feeding the transposer block the pixelvalve is unneeded and
 * should not be enabled.
 */
-- 
git-series 0.9.1


[PATCH v5 22/80] drm/vc4: crtc: Move HVS init and close to a function

2020-09-03 Thread Maxime Ripard
In order to make further refactoring easier, let's move the HVS channel
setup / teardown to their own function.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hvs.c | 104 +++
 1 file changed, 58 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index fa61cad3a53d..dde931233d4a 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -196,6 +196,62 @@ static void vc4_hvs_update_gamma_lut(struct drm_crtc *crtc)
vc4_hvs_lut_load(crtc);
 }
 
+static int vc4_hvs_init_channel(struct vc4_dev *vc4, struct drm_crtc *crtc,
+   struct drm_display_mode *mode, bool oneshot)
+{
+   struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state);
+   unsigned int chan = vc4_crtc_state->assigned_channel;
+   u32 dispctrl;
+
+   /* Turn on the scaler, which will wait for vstart to start
+* compositing.
+* When feeding the transposer, we should operate in oneshot
+* mode.
+*/
+   dispctrl = SCALER_DISPCTRLX_ENABLE;
+
+   if (!vc4->hvs->hvs5)
+   dispctrl |= VC4_SET_FIELD(mode->hdisplay,
+ SCALER_DISPCTRLX_WIDTH) |
+   VC4_SET_FIELD(mode->vdisplay,
+ SCALER_DISPCTRLX_HEIGHT) |
+   (oneshot ? SCALER_DISPCTRLX_ONESHOT : 0);
+   else
+   dispctrl |= VC4_SET_FIELD(mode->hdisplay,
+ SCALER5_DISPCTRLX_WIDTH) |
+   VC4_SET_FIELD(mode->vdisplay,
+ SCALER5_DISPCTRLX_HEIGHT) |
+   (oneshot ? SCALER5_DISPCTRLX_ONESHOT : 0);
+
+   HVS_WRITE(SCALER_DISPCTRLX(chan), dispctrl);
+
+   return 0;
+}
+
+static void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int chan)
+{
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+   if (HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE)
+   return;
+
+   HVS_WRITE(SCALER_DISPCTRLX(chan),
+ HVS_READ(SCALER_DISPCTRLX(chan)) | SCALER_DISPCTRLX_RESET);
+   HVS_WRITE(SCALER_DISPCTRLX(chan),
+ HVS_READ(SCALER_DISPCTRLX(chan)) & ~SCALER_DISPCTRLX_ENABLE);
+
+   /* Once we leave, the scaler should be disabled and its fifo empty. */
+   WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_RESET);
+
+   WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(chan)),
+  SCALER_DISPSTATX_MODE) !=
+SCALER_DISPSTATX_MODE_DISABLED);
+
+   WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(chan)) &
+ (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
+SCALER_DISPSTATX_EMPTY);
+}
+
 int vc4_hvs_atomic_check(struct drm_crtc *crtc,
 struct drm_crtc_state *state)
 {
@@ -268,63 +324,19 @@ void vc4_hvs_atomic_enable(struct drm_crtc *crtc,
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
bool oneshot = vc4_state->feed_txp;
-   u32 dispctrl;
 
vc4_hvs_update_dlist(crtc);
-
-   /* Turn on the scaler, which will wait for vstart to start
-* compositing.
-* When feeding the transposer, we should operate in oneshot
-* mode.
-*/
-   dispctrl = SCALER_DISPCTRLX_ENABLE;
-
-   if (!vc4->hvs->hvs5)
-   dispctrl |= VC4_SET_FIELD(mode->hdisplay,
- SCALER_DISPCTRLX_WIDTH) |
-   VC4_SET_FIELD(mode->vdisplay,
- SCALER_DISPCTRLX_HEIGHT) |
-   (oneshot ? SCALER_DISPCTRLX_ONESHOT : 0);
-   else
-   dispctrl |= VC4_SET_FIELD(mode->hdisplay,
- SCALER5_DISPCTRLX_WIDTH) |
-   VC4_SET_FIELD(mode->vdisplay,
- SCALER5_DISPCTRLX_HEIGHT) |
-   (oneshot ? SCALER5_DISPCTRLX_ONESHOT : 0);
-
-   HVS_WRITE(SCALER_DISPCTRLX(vc4_state->assigned_channel), dispctrl);
+   vc4_hvs_init_channel(vc4, crtc, mode, oneshot);
 }
 
 void vc4_hvs_atomic_disable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
 {
struct drm_device *dev = crtc->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(old_state);
unsigned int chan = vc4_state->assigned_channel;
 
-   if (HVS_READ(SCALER_DISPCTRLX(chan)) &
-   SCALER_DISPCTRLX_ENABLE) {
-   HVS_WRITE(SCALER_DISPCTRLX(chan),
-   

[PATCH v5 26/80] drm/vc4: crtc: Remove redundant pixelvalve reset

2020-09-03 Thread Maxime Ripard
Since we moved the pixelvalve configuration to atomic_enable, we're now
first calling the function that resets the pixelvalve and then the one that
configures it.

However, the first thing the latter is doing is calling the reset function,
meaning that we reset twice our pixelvalve. Let's remove the first call.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 2eda2e6429ec..2c5ff45dc315 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -427,7 +427,6 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 
require_hvs_enabled(dev);
 
-   vc4_crtc_pixelvalve_reset(crtc);
vc4_crtc_config_pv(crtc);
 
CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
-- 
git-series 0.9.1


[PATCH v5 29/80] drm/vc4: crtc: Add a delay after disabling the PixelValve output

2020-09-03 Thread Maxime Ripard
In order to avoid pixels getting stuck in the (unflushable) FIFO between
the HVS and the PV, we need to add some delay after disabling the PV output
and before disabling the HDMI controller. 20ms seems to be good enough so
let's use that.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index d0b326e1df0a..4c23cf8aefb9 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -403,6 +403,24 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
 
+   /*
+* This delay is needed to avoid to get a pixel stuck in an
+* unflushable FIFO between the pixelvalve and the HDMI
+* controllers on the BCM2711.
+*
+* Timing is fairly sensitive here, so mdelay is the safest
+* approach.
+*
+* If it was to be reworked, the stuck pixel happens on a
+* BCM2711 when changing mode with a good probability, so a
+* script that changes mode on a regular basis should trigger
+* the bug after less than 10 attempts. It manifests itself with
+* every pixels being shifted by one to the right, and thus the
+* last pixel of a line actually being displayed as the first
+* pixel on the next line.
+*/
+   mdelay(20);
+
if (vc4_encoder->post_crtc_disable)
vc4_encoder->post_crtc_disable(encoder);
 
-- 
git-series 0.9.1


[PATCH v5 30/80] drm/vc4: crtc: Clear the PixelValve FIFO on disable

2020-09-03 Thread Maxime Ripard
In order to avoid a stale pixel getting stuck on mode change or a disable
/ enable cycle, we need to make sure to flush the PV FIFO on disable.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 4c23cf8aefb9..73d918706f7e 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -424,8 +424,7 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
if (vc4_encoder->post_crtc_disable)
vc4_encoder->post_crtc_disable(encoder);
 
-   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
-
+   vc4_crtc_pixelvalve_reset(crtc);
vc4_hvs_atomic_disable(crtc, old_state);
 
if (vc4_encoder->post_crtc_powerdown)
-- 
git-series 0.9.1


[PATCH v5 28/80] drm/vc4: encoder: Add finer-grained encoder callbacks

2020-09-03 Thread Maxime Ripard
In the BCM2711, the setup of the HVS, pixelvalve and HDMI controller
requires very precise ordering and timing that the regular atomic callbacks
don't provide. Let's add new callbacks on top of the regular ones to be
able to split the configuration as needed.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 19 +++
 drivers/gpu/drm/vc4/vc4_drv.h  |  7 +++
 2 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index b7b0e19e2fe1..d0b326e1df0a 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -389,6 +389,8 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
 {
struct drm_device *dev = crtc->dev;
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+   struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
+   struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
int ret;
 
require_hvs_enabled(dev);
@@ -401,10 +403,16 @@ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
ret = wait_for(!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN), 1);
WARN_ONCE(ret, "Timeout waiting for !PV_VCONTROL_VIDEN\n");
 
+   if (vc4_encoder->post_crtc_disable)
+   vc4_encoder->post_crtc_disable(encoder);
+
CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
 
vc4_hvs_atomic_disable(crtc, old_state);
 
+   if (vc4_encoder->post_crtc_powerdown)
+   vc4_encoder->post_crtc_powerdown(encoder);
+
/*
 * Make sure we issue a vblank event after disabling the CRTC if
 * someone was waiting it.
@@ -424,6 +432,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 {
struct drm_device *dev = crtc->dev;
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+   struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
+   struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
 
require_hvs_enabled(dev);
 
@@ -434,15 +444,24 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 
vc4_hvs_atomic_enable(crtc, old_state);
 
+   if (vc4_encoder->pre_crtc_configure)
+   vc4_encoder->pre_crtc_configure(encoder);
+
vc4_crtc_config_pv(crtc);
 
CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
 
+   if (vc4_encoder->pre_crtc_enable)
+   vc4_encoder->pre_crtc_enable(encoder);
+
/* When feeding the transposer block the pixelvalve is unneeded and
 * should not be enabled.
 */
CRTC_WRITE(PV_V_CONTROL,
   CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
+
+   if (vc4_encoder->post_crtc_enable)
+   vc4_encoder->post_crtc_enable(encoder);
 }
 
 static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index dfcc684f5d28..251fcc35530c 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -439,6 +439,13 @@ struct vc4_encoder {
struct drm_encoder base;
enum vc4_encoder_type type;
u32 clock_select;
+
+   void (*pre_crtc_configure)(struct drm_encoder *encoder);
+   void (*pre_crtc_enable)(struct drm_encoder *encoder);
+   void (*post_crtc_enable)(struct drm_encoder *encoder);
+
+   void (*post_crtc_disable)(struct drm_encoder *encoder);
+   void (*post_crtc_powerdown)(struct drm_encoder *encoder);
 };
 
 static inline struct vc4_encoder *
-- 
git-series 0.9.1


[PATCH v5 21/80] drm/vc4: crtc: Move PV dump to config_pv

2020-09-03 Thread Maxime Ripard
Now that we only configure the PixelValve in vc4_crtc_config_pv, it doesn't
really make much sense to dump its register content in its caller.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 26 --
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index c2ab907611e3..181d3fd57bc7 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -290,6 +290,14 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
   vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
u8 ppc = pv_data->pixels_per_clock;
+   bool debug_dump_regs = false;
+
+   if (debug_dump_regs) {
+   struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev);
+   dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs before:\n",
+drm_crtc_index(crtc));
+   drm_print_regset32(&p, &vc4_crtc->regset);
+   }
 
vc4_crtc_pixelvalve_reset(crtc);
 
@@ -359,30 +367,20 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
   PV_CONTROL_WAIT_HSTART |
   VC4_SET_FIELD(vc4_encoder->clock_select,
 PV_CONTROL_CLK_SELECT));
-}
-
-static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
-{
-   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-   bool debug_dump_regs = false;
 
if (debug_dump_regs) {
struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev);
-   dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs before:\n",
+   dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs after:\n",
 drm_crtc_index(crtc));
drm_print_regset32(&p, &vc4_crtc->regset);
}
+}
 
+static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
vc4_crtc_config_pv(crtc);
 
vc4_hvs_mode_set_nofb(crtc);
-
-   if (debug_dump_regs) {
-   struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev);
-   dev_info(&vc4_crtc->pdev->dev, "CRTC %d regs after:\n",
-drm_crtc_index(crtc));
-   drm_print_regset32(&p, &vc4_crtc->regset);
-   }
 }
 
 static void require_hvs_enabled(struct drm_device *dev)
-- 
git-series 0.9.1


[PATCH v5 23/80] drm/vc4: crtc: Move the HVS gamma LUT setup to our init function

2020-09-03 Thread Maxime Ripard
Since most of the HVS channel is setup in the init function, let's move the
gamma setup there too. As this makes the HVS mode_set function empty, let's
remove it in the process.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c |  2 +-
 drivers/gpu/drm/vc4/vc4_drv.h  |  1 +-
 drivers/gpu/drm/vc4/vc4_hvs.c  | 59 +--
 drivers/gpu/drm/vc4/vc4_txp.c  |  1 +-
 4 files changed, 16 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 181d3fd57bc7..284a85b9d7d4 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -379,8 +379,6 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
 static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
vc4_crtc_config_pv(crtc);
-
-   vc4_hvs_mode_set_nofb(crtc);
 }
 
 static void require_hvs_enabled(struct drm_device *dev)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 4126506b3a69..dfcc684f5d28 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -904,7 +904,6 @@ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct 
drm_crtc_state *state);
 void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state 
*old_state);
 void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state 
*old_state);
 void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *state);
-void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc);
 void vc4_hvs_dump_state(struct drm_device *dev);
 void vc4_hvs_unmask_underrun(struct drm_device *dev, int channel);
 void vc4_hvs_mask_underrun(struct drm_device *dev, int channel);
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index dde931233d4a..efaae60bb323 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -201,6 +201,8 @@ static int vc4_hvs_init_channel(struct vc4_dev *vc4, struct 
drm_crtc *crtc,
 {
struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state);
unsigned int chan = vc4_crtc_state->assigned_channel;
+   bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
+   u32 dispbkgndx;
u32 dispctrl;
 
/* Turn on the scaler, which will wait for vstart to start
@@ -225,6 +227,20 @@ static int vc4_hvs_init_channel(struct vc4_dev *vc4, 
struct drm_crtc *crtc,
 
HVS_WRITE(SCALER_DISPCTRLX(chan), dispctrl);
 
+   dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(chan));
+   dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
+   dispbkgndx &= ~SCALER_DISPBKGND_INTERLACE;
+
+   HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx |
+ SCALER_DISPBKGND_AUTOHS |
+ ((!vc4->hvs->hvs5) ? SCALER_DISPBKGND_GAMMA : 0) |
+ (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
+
+   /* Reload the LUT, since the SRAMs would have been disabled if
+* all CRTCs had SCALER_DISPBKGND_GAMMA unset at once.
+*/
+   vc4_hvs_lut_load(crtc);
+
return 0;
 }
 
@@ -421,49 +437,6 @@ void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
}
 }
 
-void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc)
-{
-   struct drm_device *dev = crtc->dev;
-   struct vc4_dev *vc4 = to_vc4_dev(dev);
-   struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
-   struct drm_display_mode *mode = &crtc->state->adjusted_mode;
-   bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
-
-   if (vc4_state->assigned_channel == 2) {
-   u32 dispctrl;
-   u32 dsp3_mux;
-
-   /*
-* SCALER_DISPCTRL_DSP3 = X, where X < 2 means 'connect DSP3 to
-* FIFO X'.
-* SCALER_DISPCTRL_DSP3 = 3 means 'disable DSP 3'.
-*
-* DSP3 is connected to FIFO2 unless the transposer is
-* enabled. In this case, FIFO 2 is directly accessed by the
-* TXP IP, and we need to disable the FIFO2 -> pixelvalve1
-* route.
-*/
-   if (vc4_state->feed_txp)
-   dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX);
-   else
-   dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
-
-   dispctrl = HVS_READ(SCALER_DISPCTRL) &
-  ~SCALER_DISPCTRL_DSP3_MUX_MASK;
-   HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux);
-   }
-
-   HVS_WRITE(SCALER_DISPBKGNDX(vc4_state->assigned_channel),
- SCALER_DISPBKGND_AUTOHS |
- ((!vc4->hvs->hvs5) ? SCALER_DISPBKGND_GAMMA : 0) |
- (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
-
-   /* Reload the LUT, since the SRAMs would have been disabled if
-* all CRTCs had SCALER_DISPBKGND_GAMMA unset at once.
-*/

[PATCH v5 25/80] drm/vc4: crtc: Remove mode_set_nofb

2020-09-03 Thread Maxime Ripard
On BCM2711 to avoid stale pixels getting stuck in intermediate FIFOs, the
pixelvalve needs to be setup each time there's a mode change or enable /
disable sequence.

Therefore, we can't really use mode_set_nofb anymore to configure it, but
we need to move it to atomic_enable.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 284a85b9d7d4..2eda2e6429ec 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -376,11 +376,6 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
}
 }
 
-static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
-{
-   vc4_crtc_config_pv(crtc);
-}
-
 static void require_hvs_enabled(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -433,6 +428,7 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
require_hvs_enabled(dev);
 
vc4_crtc_pixelvalve_reset(crtc);
+   vc4_crtc_config_pv(crtc);
 
CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
 
@@ -791,7 +787,6 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = {
 };
 
 static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
-   .mode_set_nofb = vc4_crtc_mode_set_nofb,
.mode_valid = vc4_crtc_mode_valid,
.atomic_check = vc4_crtc_atomic_check,
.atomic_flush = vc4_hvs_atomic_flush,
-- 
git-series 0.9.1


[PATCH v5 19/80] drm/vc4: crtc: Disable color management for HVS5

2020-09-03 Thread Maxime Ripard
The HVS5 uses different color matrices. Disable color management support
for now.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 17 +++--
 drivers/gpu/drm/vc4/vc4_hvs.c  |  2 +-
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 04744223460a..41bc61d5a61f 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -874,6 +874,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
*vc4_crtc,
  const struct drm_crtc_funcs *crtc_funcs,
  const struct drm_crtc_helper_funcs *crtc_helper_funcs)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(drm);
struct drm_crtc *crtc = &vc4_crtc->base;
struct drm_plane *primary_plane;
unsigned int i;
@@ -893,13 +894,17 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
*vc4_crtc,
drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
  crtc_funcs, NULL);
drm_crtc_helper_add(crtc, crtc_helper_funcs);
-   drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
-   drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
 
-   /* We support CTM, but only for one CRTC at a time. It's therefore
-* implemented as private driver state in vc4_kms, not here.
-*/
-   drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
+   if (!vc4->hvs->hvs5) {
+   drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
+
+   drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
+
+   /* We support CTM, but only for one CRTC at a time. It's 
therefore
+* implemented as private driver state in vc4_kms, not here.
+*/
+   drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
+   }
 
for (i = 0; i < crtc->gamma_size; i++) {
vc4_crtc->lut_r[i] = i;
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 31a9bc5ef84e..fa61cad3a53d 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -443,7 +443,7 @@ void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc)
 
HVS_WRITE(SCALER_DISPBKGNDX(vc4_state->assigned_channel),
  SCALER_DISPBKGND_AUTOHS |
- SCALER_DISPBKGND_GAMMA |
+ ((!vc4->hvs->hvs5) ? SCALER_DISPBKGND_GAMMA : 0) |
  (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
 
/* Reload the LUT, since the SRAMs would have been disabled if
-- 
git-series 0.9.1


[PATCH v5 18/80] drm/vc4: crtc: Add HDMI1 encoder type

2020-09-03 Thread Maxime Ripard
The BCM2711 sports a second HDMI controller, so let's add that second HDMI
encoder type.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_drv.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 5781773aec4b..4126506b3a69 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -427,6 +427,7 @@ to_vc4_plane_state(struct drm_plane_state *state)
 enum vc4_encoder_type {
VC4_ENCODER_TYPE_NONE,
VC4_ENCODER_TYPE_HDMI0,
+   VC4_ENCODER_TYPE_HDMI1,
VC4_ENCODER_TYPE_VEC,
VC4_ENCODER_TYPE_DSI0,
VC4_ENCODER_TYPE_DSI1,
-- 
git-series 0.9.1


Re: [PATCH] mmc: sdhci-msm: Prefer asynchronous probe

2020-09-03 Thread Ulf Hansson
On Thu, 3 Sep 2020 at 01:43, Douglas Anderson  wrote:
>
> Turning on initcall debug on one system showed this:
>   initcall sdhci_msm_driver_init+0x0/0x28 returned 0 after 34782 usecs
>
> The lion's share of this time (~33 ms) was in mmc_power_up().  This
> shouldn't be terribly surprising since there are a few calls to delay
> based on "power_delay_ms" and the default delay there is 10 ms.
>
> Because we haven't specified that we'd prefer asynchronous probe for
> this driver then we'll wait for this driver to finish before we start
> probes for more drivers.  While 33 ms doesn't sound like tons, every
> little bit counts.
>
> There should be little problem with turning on asynchronous probe for
> this driver.  It's already possible that previous drivers may have
> turned on asynchronous probe so we might already have other things
> (that probed before us) probing at the same time we are anyway.  This
> driver isn't really providing resources (clocks, regulators, etc) that
> other drivers need to probe and even if it was they should be handling
> -EPROBE_DEFER.
>
> Let's turn this on and get a bit of boot speed back.

Thanks for a very well written commit message!

Indeed, I am sure many mmc host drivers could benefit from a similar
change. At least regular platform drivers and amba drivers are pretty
sure to work, but who knows.

>
> Signed-off-by: Douglas Anderson 

Applied for next, thanks!

Kind regards
Uffe


> ---
>
>  drivers/mmc/host/sdhci-msm.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
> index d4c02884cca8..9dd0dbb65382 100644
> --- a/drivers/mmc/host/sdhci-msm.c
> +++ b/drivers/mmc/host/sdhci-msm.c
> @@ -2542,6 +2542,7 @@ static struct platform_driver sdhci_msm_driver = {
>.name = "sdhci_msm",
>.of_match_table = sdhci_msm_dt_match,
>.pm = &sdhci_msm_pm_ops,
> +  .probe_type = PROBE_PREFER_ASYNCHRONOUS,
> },
>  };
>
> --
> 2.28.0.402.g5ffc5be6b7-goog
>


Re: [PATCH 2/3] mmc: s3cmci: Use proper printk format for iomem pointer

2020-09-03 Thread Ulf Hansson
On Wed, 2 Sep 2020 at 22:49, Krzysztof Kozlowski  wrote:
>
> iomem pointers should be printed with pointer format to hide the
> actual value and fix warnings when compile testing for 64-bit
> architecture:
>
>   drivers/mmc/host/s3cmci.c:1355:46: warning:
> cast from pointer to integer of different size [-Wpointer-to-int-cast]
>
> Signed-off-by: Krzysztof Kozlowski 

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/s3cmci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
> index dcd458649338..3fb597095079 100644
> --- a/drivers/mmc/host/s3cmci.c
> +++ b/drivers/mmc/host/s3cmci.c
> @@ -1352,7 +1352,7 @@ static int s3cmci_state_show(struct seq_file *seq, void 
> *v)
>  {
> struct s3cmci_host *host = seq->private;
>
> -   seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
> +   seq_printf(seq, "Register base = 0x%p\n", host->base);
> seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
> seq_printf(seq, "Prescale = %d\n", host->prescaler);
> seq_printf(seq, "is2440 = %d\n", host->is2440);
> --
> 2.17.1
>


[PATCH v5 17/80] drm/vc4: crtc: Rename HDMI encoder type to HDMI0

2020-09-03 Thread Maxime Ripard
The previous generations were only supporting a single HDMI controller, but
that's about to change, so put an index as well to differentiate between
the two controllers.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
 drivers/gpu/drm/vc4/vc4_drv.h  | 2 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 1d9e3658ae59..04744223460a 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -835,7 +835,7 @@ static const struct vc4_pv_data bcm2835_pv2_data = {
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
-   [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI,
+   [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI0,
[PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
},
 };
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 179010b9a010..5781773aec4b 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -426,7 +426,7 @@ to_vc4_plane_state(struct drm_plane_state *state)
 
 enum vc4_encoder_type {
VC4_ENCODER_TYPE_NONE,
-   VC4_ENCODER_TYPE_HDMI,
+   VC4_ENCODER_TYPE_HDMI0,
VC4_ENCODER_TYPE_VEC,
VC4_ENCODER_TYPE_DSI0,
VC4_ENCODER_TYPE_DSI1,
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 15a11cd4de25..ec34c08b16df 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1309,7 +1309,7 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
GFP_KERNEL);
if (!vc4_hdmi_encoder)
return -ENOMEM;
-   vc4_hdmi_encoder->base.type = VC4_ENCODER_TYPE_HDMI;
+   vc4_hdmi_encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
hdmi->encoder = &vc4_hdmi_encoder->base.base;
 
hdmi->pdev = pdev;
-- 
git-series 0.9.1


Re: [PATCH] irqchip/tango: Fix possible null ptr reference in tangox_irq_init

2020-09-03 Thread Marc Zyngier

On 2020-09-03 02:59, Ye Bin wrote:

In tangox_irq_init allocate chip but not test.

Signed-off-by: Ye Bin 
---
 drivers/irqchip/irq-tango.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/irqchip/irq-tango.c b/drivers/irqchip/irq-tango.c
index 34290f09b853..25da120230ad 100644
--- a/drivers/irqchip/irq-tango.c
+++ b/drivers/irqchip/irq-tango.c
@@ -187,6 +187,8 @@ static int __init tangox_irq_init(void __iomem
*base, struct resource *baseres,
panic("%pOFn: failed to get address", node);

chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+   if (!chip)
+   panic("%pOFn: failed to get chip", node);
chip->ctl = res.start - baseres->start;
chip->base = base;


So you are trading a panic for a panic? What is the point?
A failing kzalloc already gives you all the information you may
need.

M.
--
Jazz is not dead. It just smells funny...


Re: [PATCH v2] mmc: sdhci-of-esdhc: Don't walk device-tree on every interrupt

2020-09-03 Thread Ulf Hansson
On Thu, 3 Sep 2020 at 03:20, Chris Packham
 wrote:
>
> Commit b214fe592ab7 ("mmc: sdhci-of-esdhc: add erratum eSDHC7 support")
> added code to check for a specific compatible string in the device-tree
> on every esdhc interrupat. Instead of doing this record the quirk in
> struct sdhci_esdhc and lookup the struct in esdhc_irq.
>
> Signed-off-by: Chris Packham 

Applied for fixes, and by adding a stable tag, thanks!

Kind regards
Uffe


> ---
> I found this in passing while trying to track down another issue using ftrace.
> I found it odd that I was seeing a lot of calls to __of_device_is_compatible()
> coming from esdhc_irq() (the fact that this interrupt is going off on my board
> is also odd, but that's a different story).
>
> Changes in v2:
> - add quirk_trans_complete_erratum to struct sdhci_esdhc so all the dt 
> handling
>   is taken care of in esdhc_init.
>
>  drivers/mmc/host/sdhci-of-esdhc.c | 10 +++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c 
> b/drivers/mmc/host/sdhci-of-esdhc.c
> index 7c73d243dc6c..45881b309956 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -81,6 +81,7 @@ struct sdhci_esdhc {
> bool quirk_tuning_erratum_type2;
> bool quirk_ignore_data_inhibit;
> bool quirk_delay_before_data_reset;
> +   bool quirk_trans_complete_erratum;
> bool in_sw_tuning;
> unsigned int peripheral_clock;
> const struct esdhc_clk_fixup *clk_fixup;
> @@ -1177,10 +1178,11 @@ static void esdhc_set_uhs_signaling(struct sdhci_host 
> *host,
>
>  static u32 esdhc_irq(struct sdhci_host *host, u32 intmask)
>  {
> +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +   struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> u32 command;
>
> -   if (of_find_compatible_node(NULL, NULL,
> -   "fsl,p2020-esdhc")) {
> +   if (esdhc->quirk_trans_complete_erratum) {
> command = SDHCI_GET_CMD(sdhci_readw(host,
> SDHCI_COMMAND));
> if (command == MMC_WRITE_MULTIPLE_BLOCK &&
> @@ -1334,8 +1336,10 @@ static void esdhc_init(struct platform_device *pdev, 
> struct sdhci_host *host)
> esdhc->clk_fixup = match->data;
> np = pdev->dev.of_node;
>
> -   if (of_device_is_compatible(np, "fsl,p2020-esdhc"))
> +   if (of_device_is_compatible(np, "fsl,p2020-esdhc")) {
> esdhc->quirk_delay_before_data_reset = true;
> +   esdhc->quirk_trans_complete_erratum = true;
> +   }
>
> clk = of_clk_get(np, 0);
> if (!IS_ERR(clk)) {
> --
> 2.28.0
>


Re: [PATCH 1/3] mmc: davinci: Fix -Wpointer-to-int-cast on compile test

2020-09-03 Thread Ulf Hansson
On Wed, 2 Sep 2020 at 22:48, Krzysztof Kozlowski  wrote:
>
> Store in interrupt service routine always '1' in end_command, not the
> value of host->cmd to fix compile test warnings on RISC-V:
>
>   drivers/mmc/host/davinci_mmc.c:999:17: warning:
> cast from pointer to integer of different size [-Wpointer-to-int-cast]
>
> Signed-off-by: Krzysztof Kozlowski 

Applied for next, thanks!

Kind regards
Uffe


> ---
>
> Follow up to:
> https://lore.kernel.org/linux-arm-kernel/20200902193658.20539-1-k...@kernel.org/T/#t
>
>  drivers/mmc/host/davinci_mmc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
> index fad1010fb52b..66d740ee7d45 100644
> --- a/drivers/mmc/host/davinci_mmc.c
> +++ b/drivers/mmc/host/davinci_mmc.c
> @@ -996,7 +996,7 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
>
> if (qstatus & MMCST0_RSPDNE) {
> /* End of command phase */
> -   end_command = (int) host->cmd;
> +   end_command = host->cmd ? 1 : 0;
> }
>
> if (end_command)
> --
> 2.17.1
>


Re: [RFT 06/11] mmc: sdhci-brcmstb: Simplify with optional clock and dev_err_probe()

2020-09-03 Thread Ulf Hansson
On Wed, 2 Sep 2020 at 21:58, Florian Fainelli  wrote:
>
>
>
> On 9/2/2020 12:36 PM, Krzysztof Kozlowski wrote:
> > Only -ENOENT from devm_clk_get() means that clock is not present in
> > device tree.  Other errors have their own meaning and should not be
> > ignored.
> >
> > Simplify getting the clock which is in fact optional and also use
> > dev_err_probe() for handling deferred.
> >
> > Signed-off-by: Krzysztof Kozlowski 
>
> This is actually an open coded version of devm_clk_get_optional(), so
> this is fine:

devm_clk_get_optional() treats -ENOENT specifically, so it's not an
exact open coded version. I think that's why Krzysztof prefered to get
it tested on HW.

>
> Acked-by: Florian Fainelli 

Thanks!

I am queuing this up for next, without waiting for explicit tests .
There is time to get that from testing in linux-next anyway.

Kind regards
Uffe


Re: [PATCH] mmc: s3cmci: Drop unused variables in dbg_dumpregs

2020-09-03 Thread Ulf Hansson
On Thu, 3 Sep 2020 at 07:43, Krzysztof Kozlowski  wrote:
>
> The 'imask' and 'bsize' are not used in dbg_dumpregs:
>
>   drivers/mmc/host/s3cmci.c:149:36: warning: variable 'imask' set but not 
> used [-Wunused-but-set-variable]
>   drivers/mmc/host/s3cmci.c:148:63: warning: variable 'bsize' set but not 
> used [-Wunused-but-set-variable]
>
> Reported-by: kernel test robot 
> Signed-off-by: Krzysztof Kozlowski 

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/s3cmci.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
> index ac94f926624d..40329aeacfdf 100644
> --- a/drivers/mmc/host/s3cmci.c
> +++ b/drivers/mmc/host/s3cmci.c
> @@ -145,8 +145,8 @@ static void s3cmci_reset(struct s3cmci_host *host);
>
>  static void dbg_dumpregs(struct s3cmci_host *host, char *prefix)
>  {
> -   u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize;
> -   u32 datcon, datcnt, datsta, fsta, imask;
> +   u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer;
> +   u32 datcon, datcnt, datsta, fsta;
>
> con = readl(host->base + S3C2410_SDICON);
> pre = readl(host->base + S3C2410_SDIPRE);
> @@ -158,12 +158,10 @@ static void dbg_dumpregs(struct s3cmci_host *host, char 
> *prefix)
> r2  = readl(host->base + S3C2410_SDIRSP2);
> r3  = readl(host->base + S3C2410_SDIRSP3);
> timer   = readl(host->base + S3C2410_SDITIMER);
> -   bsize   = readl(host->base + S3C2410_SDIBSIZE);
> datcon  = readl(host->base + S3C2410_SDIDCON);
> datcnt  = readl(host->base + S3C2410_SDIDCNT);
> datsta  = readl(host->base + S3C2410_SDIDSTA);
> fsta= readl(host->base + S3C2410_SDIFSTA);
> -   imask   = readl(host->base + host->sdiimsk);
>
> dbg(host, dbg_debug, "%s  CON:[%08x]  PRE:[%08x]  TMR:[%08x]\n",
> prefix, con, pre, timer);
> --
> 2.17.1
>


Re: [PATCH v2] mmc: mmc_spi: Allow the driver to be built when CONFIG_HAS_DMA is unset

2020-09-03 Thread Ulf Hansson
On Thu, 3 Sep 2020 at 02:41, Rich Felker  wrote:
>
> On Wed, Sep 02, 2020 at 05:51:16PM +0200, Geert Uytterhoeven wrote:
> > Hi Rich,
> >
> > On Wed, Sep 2, 2020 at 5:43 PM Rich Felker  wrote:
> > > On Wed, Sep 02, 2020 at 10:31:47AM +0200, Ulf Hansson wrote:
> > > > On Tue, 1 Sep 2020 at 17:40, Christoph Hellwig  wrote:
> > > > > On Tue, Sep 01, 2020 at 05:36:17PM +0200, Ulf Hansson wrote:
> > > > > > > I still don't think this makes sense, as the dma_mask should 
> > > > > > > always
> > > > > > > be non-NULL here.
> > > > > >
> > > > > > If that is the case, I wonder how the driver could even have worked 
> > > > > > without DMA.
> > > > > >
> > > > > > Because in the existing code, host->dma_dev gets assigned to
> > > > > > spi->master->dev.parent->dma_mask - which seems to turn on the DMA
> > > > > > usage in the driver.
> > > > > >
> > > > > > What am I missing?
> > > > >
> > > > > Do you know of other non-DMA users?  For SH nommu it probably worked
> > > >
> > > > I don't know of other non-DMA users. As I said, I wish someone could
> > > > step in and take better care of mmc_spi - as I know it's being used a
> > > > lot.
> > > >
> > > > > because SH nommu used to provide a DMA implementation that worked
> > > > > fine for streaming maps, but was completely broken for coherent
> > > > > allocation.  And this driver appears to only use the former.
> > > >
> > > > Alright, so you are saying the DMA support may potentially never have
> > > > been optional to this driver. In any case, I can remove the check in
> > > > $subject patch, as it shouldn't matter.
> > >
> > > DMA support was always optional, because even on systems where DMA is
> > > present, it doesn't necessarily mean the SPI controller uses DMA. In
> > > particular, pure bit-banged SPI via GPIOs doesn't have DMA, but has
> > > always worked. See my previous reply to Christoph about host->dma_dev
> > > for my current-best understanding of what's going on here.
> > >
> > > > Anyway, let's see what Rich thinks of this. I am curious to see if the
> > > > patch works on his SH boards - as I haven't been able to test it.
> > >
> > > I'll rebuild and retest just to confirm, but I already tested a
> > > functionally equivalent patch that just did the #ifdef inline (rather
> > > than moving the logic out to separate functions) and it worked fine.
> >
> > Hence, Tested-by? ;-)
>
> Confirmed that this version of the patch works too. Thus,
>
> Tested-by: Rich Felker 

I have applied the patch for fixes, thanks for testing!

Christoph, when it comes to the check of
"spi->master->dev.parent->dma_mask", I am keeping it for now. I am
simply not sure that all spi masters assign the pointer (even if most
are platform drivers). I think it's better that we remove that check
in a separate patch - to get it tested.

Kind regards
Uffe


Re: [PATCH 3/3] mmc: s3cmci: Cast driver data through long

2020-09-03 Thread Ulf Hansson
On Wed, 2 Sep 2020 at 22:49, Krzysztof Kozlowski  wrote:
>
> Since driver data is a pointer, direct casting to integer causes
> warning when compile testing for 64-bit architecture:
>
>   drivers/mmc/host/s3cmci.c:1495:17: warning: cast from pointer to integer of 
> different size [-Wpointer-to-int-cast]
>
> The actual driver data can be only 0 or 1, so cast it via long and do
> not care about any loss of value.
>
> Signed-off-by: Krzysztof Kozlowski 

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/s3cmci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
> index 3fb597095079..ac94f926624d 100644
> --- a/drivers/mmc/host/s3cmci.c
> +++ b/drivers/mmc/host/s3cmci.c
> @@ -1492,7 +1492,7 @@ static int s3cmci_probe_dt(struct s3cmci_host *host)
> struct mmc_host *mmc = host->mmc;
> int ret;
>
> -   host->is2440 = (int) of_device_get_match_data(&pdev->dev);
> +   host->is2440 = (long) of_device_get_match_data(&pdev->dev);
>
> ret = mmc_of_parse(mmc);
> if (ret)
> --
> 2.17.1
>


Re: [PATCH 00/11] mmc: Minor cleanups and compile test

2020-09-03 Thread Ulf Hansson
On Wed, 2 Sep 2020 at 21:37, Krzysztof Kozlowski  wrote:
>
> Hi,
>
> Set of minor cleanups.  Patches requiring more attention:
>  - 6/11: Testing and review would be appreciated,
>  - 11/11: I build tested multiple architectures but not all and
>definitely no all possible configs. This one could sit on the lists
>for few days so 0-day would try it.
>
> Best regards,
> Krzysztof
>
> Krzysztof Kozlowski (11):
>   mmc: bcm2835: Simplify with dev_err_probe()
>   mmc: davinci: Simplify with dev_err_probe()
>   mmc: dw_mmc-zx: Simplify with dev_err_probe()
>   mmc: jz4740: Simplify with dev_err_probe()
>   mmc: meson: Simplify with dev_err_probe()
>   mmc: sdhci-brcmstb: Simplify with optional clock and dev_err_probe()
>   mmc: sdhci-of-arasan: Simplify with dev_err_probe()
>   mmc: sdhci-tegra: Simplify with dev_err_probe()
>   mmc: dw_mmc: Simplify with dev_err_probe()
>   mmc: sdhci-of-sparx5: Use proper printk format for dma_addr_t
>   mmc: host: Enable compile testing of multiple drivers
>
>  drivers/mmc/host/Kconfig   | 42 --
>  drivers/mmc/host/bcm2835.c |  4 +--
>  drivers/mmc/host/davinci_mmc.c |  5 ++--
>  drivers/mmc/host/dw_mmc-zx.c   | 11 +++-
>  drivers/mmc/host/dw_mmc.c  |  9 +++
>  drivers/mmc/host/jz4740_mmc.c  |  5 ++--
>  drivers/mmc/host/meson-gx-mmc.c| 16 
>  drivers/mmc/host/sdhci-brcmstb.c   | 12 -
>  drivers/mmc/host/sdhci-of-arasan.c |  7 +++--
>  drivers/mmc/host/sdhci-of-sparx5.c |  4 +--
>  drivers/mmc/host/sdhci-tegra.c |  7 ++---
>  11 files changed, 51 insertions(+), 71 deletions(-)
>
> --
> 2.17.1
>

Series applied for next, except 11, thanks!

Kind regards
Uffe


[PATCH v5 31/80] drm/vc4: crtc: Clear the PixelValve FIFO during configuration

2020-09-03 Thread Maxime Ripard
Even though it's not really clear why we need to flush the PV FIFO during
the configuration even though we started by flushing it, experience shows
that without it we get a stale pixel stuck in the FIFO between the HVS and
the PV.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 73d918706f7e..00b2c2b011d1 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -358,7 +358,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
if (is_dsi)
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 
-   CRTC_WRITE(PV_CONTROL,
+   CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR |
   vc4_crtc_get_fifo_full_level_bits(vc4_crtc, format) |
   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
   VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
-- 
git-series 0.9.1


Re: [PATCH v6 00/20] gpio: cdev: add uAPI v2

2020-09-03 Thread Bartosz Golaszewski
On Mon, Aug 31, 2020 at 5:21 AM Kent Gibson  wrote:
>
> This patchset defines and implements a new version of the
> GPIO CDEV uAPI to address existing 32/64-bit alignment issues, add
> support for debounce, event sequence numbers, and allow for requested
> lines with different configurations.
> It provides some future proofing by adding optional configuration fields
> and padding reserved for future use.
>
> The series can be partitioned into three blocks; the first two patches
> are minor fixes that impact later patches, the next eleven contain the
> v2 uAPI definition and implementation, and the final seven port the GPIO
> tools to the v2 uAPI and extend them to use new uAPI features.
>
> The more complicated patches include their own commentary where
> appropriate.
>
> Cheers,
> Kent.
>
> Changes for v6:
>  - flags variable in linereq_create() should be u64 not unsigned long
>(patch 07)
>  - remove restrictions on configuration changes - any change from one
>valid state to another valid state is allowed. (patches 09, 10, 12)
>
> Changes for v5:
>
> All changes for v5 fix issues with the gpiolib-cdev.c implementation,
> in patches 07-12.
> The uAPI is unchanged from v4, as is the port of the tools.
>
>  - use IS_ALIGNED in BUILD_BUG_ON checks (patch 07)
>  - relocate BUILD_BUG_ON checks to gpiolib_cdev_register (patch 07)
>  - s/requies/requires/ (patch 07)
>  - use unsigned int for variables that are never negative
>  - change lineinfo_get() parameter from cmd to bool watch (patch 08)
>  - flagsv2 in gpio_v2_line_info_to_v1() should be u64, not int (patch 08)
>  - change "_locked" suffixed function names to "_unlocked" (patch 10 and
>11)
>  - be less eager breaking long lines
>  - move commentary into checkin comment where appropriate - particularly
>patch 12
>  - restructure the request/line split - rename struct line to
>struct linereq, and struct edge_detector to struct line, and relocate
>the desc field from linereq to line.  The linereq name was selected
>over line_request as function names such as linereq_set_values() are
>more clearly associated with requests than line_request_set_values(),
>particularly as there is also a struct line.  And linereq is as
>informative as linerequest, so I went with the shortened form.
>
> Changes for v4:
>  - bitmap width clarification in gpiod.h (patch 04)
>  - fix info offset initialisation bug (patch 08 and inserting patch 01)
>  - replace strncpy with strscpy to remove compiler warnings
>(patch 08 and inserting patch 02)
>  - fix mask handling in line_get_values (patch 07)
>
> Changes for v3:
>  - disabling the character device from the build requires EXPERT
>  - uAPI revisions (see patch 02)
>  - replace padding_not_zeroed with calls to memchr_inv
>  - don't use bitops on 64-bit flags as that doesn't work on BE-32
>  - accept first attribute matching a line in gpio_v2_line_config.attrs
>rather than the last
>  - rework lsgpio port to uAPI v2 as flags reverted to v1 like layout
>(since patch v2)
>  - swapped patches 17 and 18 to apply debounce to multiple monitored
>lines
>
> Changes for v2:
>  - split out cleanup patches into a separate series.
>  - split implementation patch into a patch for each ioctl or major feature.
>  - split tool port patch into a patch per tool.
>  - rework uAPI to allow requested lines with different configurations.
>
> Kent Gibson (20):
>   gpiolib: cdev: desc_to_lineinfo should set info offset
>   gpiolib: cdev: replace strncpy with strscpy
>   gpio: uapi: define GPIO_MAX_NAME_SIZE for array sizes
>   gpio: uapi: define uAPI v2
>   gpiolib: make cdev a build option
>   gpiolib: add build option for CDEV v1 ABI
>   gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and
> GPIO_V2_LINE_GET_VALUES_IOCTL
>   gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and
> GPIO_V2_GET_LINEINFO_WATCH_IOCTL
>   gpiolib: cdev: support edge detection for uAPI v2
>   gpiolib: cdev: support GPIO_V2_LINE_SET_CONFIG_IOCTL
>   gpiolib: cdev: support GPIO_V2_LINE_SET_VALUES_IOCTL
>   gpiolib: cdev: support setting debounce
>   gpio: uapi: document uAPI v1 as deprecated
>   tools: gpio: port lsgpio to v2 uAPI
>   tools: gpio: port gpio-watch to v2 uAPI
>   tools: gpio: rename nlines to num_lines
>   tools: gpio: port gpio-hammer to v2 uAPI
>   tools: gpio: port gpio-event-mon to v2 uAPI
>   tools: gpio: add multi-line monitoring to gpio-event-mon
>   tools: gpio: add debounce support to gpio-event-mon
>
>  drivers/gpio/Kconfig|   29 +-
>  drivers/gpio/Makefile   |2 +-
>  drivers/gpio/gpiolib-cdev.c | 1273 +--
>  drivers/gpio/gpiolib-cdev.h |   15 +
>  drivers/gpio/gpiolib.c  |5 +
>  drivers/gpio/gpiolib.h  |6 +
>  include/uapi/linux/gpio.h   |  316 -
>  tools/gpio/gpio-event-mon.c |  146 ++--
>  tools/gpio/gpio-hammer.c|   56 +-
>  tools/gpio/gpio-utils.c |  127 ++--
>  tools/gpio/gpio-utils.h |   50 +-
>  tools/gpio

[PATCH v5 16/80] drm/vc4: crtc: Add function to compute FIFO level bits

2020-09-03 Thread Maxime Ripard
The longer FIFOs in vc5 pixelvalves means that the FIFO full level
doesn't fit in the original register field and that we also have a
secondary field. In order to prepare for this, let's move the registers
fill part to a helper function.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 2c64efd2d3d9..1d9e3658ae59 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -234,6 +234,15 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc 
*vc4_crtc, u32 format)
}
 }
 
+static u32 vc4_crtc_get_fifo_full_level_bits(struct vc4_crtc *vc4_crtc,
+u32 format)
+{
+   u32 level = vc4_get_fifo_full_level(vc4_crtc, format);
+
+   return VC4_SET_FIELD(level & 0x3f,
+PV_CONTROL_FIFO_LEVEL);
+}
+
 /*
  * Returns the encoder attached to the CRTC.
  *
@@ -336,9 +345,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 
CRTC_WRITE(PV_CONTROL,
+  vc4_crtc_get_fifo_full_level_bits(vc4_crtc, format) |
   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
-  VC4_SET_FIELD(vc4_get_fifo_full_level(vc4_crtc, format),
-PV_CONTROL_FIFO_LEVEL) |
   VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
   PV_CONTROL_CLR_AT_START |
   PV_CONTROL_TRIGGER_UNDERFLOW |
-- 
git-series 0.9.1


[PATCH v5 20/80] drm/vc4: crtc: Turn pixelvalve reset into a function

2020-09-03 Thread Maxime Ripard
The driver resets the pixelvalve FIFO in a number of occurences without
always using the same sequence.

Since this will be critical for BCM2711, let's move that sequence to a
function so that we are consistent.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 41bc61d5a61f..c2ab907611e3 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -267,6 +267,15 @@ static struct drm_encoder *vc4_get_crtc_encoder(struct 
drm_crtc *crtc)
return NULL;
 }
 
+static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
+{
+   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+
+   /* The PV needs to be disabled before it can be flushed */
+   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN);
+   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR);
+}
+
 static void vc4_crtc_config_pv(struct drm_crtc *crtc)
 {
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
@@ -282,10 +291,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
u8 ppc = pv_data->pixels_per_clock;
 
-   /* Reset the PV fifo. */
-   CRTC_WRITE(PV_CONTROL, 0);
-   CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
-   CRTC_WRITE(PV_CONTROL, 0);
+   vc4_crtc_pixelvalve_reset(crtc);
 
CRTC_WRITE(PV_HORZA,
   VC4_SET_FIELD((mode->htotal - mode->hsync_end) * pixel_rep / 
ppc,
@@ -430,9 +436,9 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
 
require_hvs_enabled(dev);
 
-   /* Reset the PV fifo. */
-   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) |
-  PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
+   vc4_crtc_pixelvalve_reset(crtc);
+
+   CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
 
/* Enable vblank irq handling before crtc is started otherwise
 * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist().
-- 
git-series 0.9.1


[PATCH 17/19] z2ram: reindent

2020-09-03 Thread Christoph Hellwig
reindent the driver using Lident as the code style was far away from
normal Linux code.

Signed-off-by: Christoph Hellwig 
---
 drivers/block/z2ram.c | 493 --
 1 file changed, 236 insertions(+), 257 deletions(-)

diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index 0e734802ee7cc6..eafecc9a72b38d 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -42,7 +42,6 @@
 
 #include 
 
-
 #define Z2MINOR_COMBINED  (0)
 #define Z2MINOR_Z2ONLY(1)
 #define Z2MINOR_CHIPONLY  (2)
@@ -50,17 +49,17 @@
 #define Z2MINOR_MEMLIST2  (5)
 #define Z2MINOR_MEMLIST3  (6)
 #define Z2MINOR_MEMLIST4  (7)
-#define Z2MINOR_COUNT (8) /* Move this down when adding a new minor */
+#define Z2MINOR_COUNT (8)  /* Move this down when adding a new 
minor */
 
 #define Z2RAM_CHUNK1024   ( Z2RAM_CHUNKSIZE >> 10 )
 
 static DEFINE_MUTEX(z2ram_mutex);
-static u_long *z2ram_map= NULL;
-static u_long z2ram_size= 0;
-static int z2_count = 0;
-static int chip_count   = 0;
-static int list_count   = 0;
-static int current_device   = -1;
+static u_long *z2ram_map = NULL;
+static u_long z2ram_size = 0;
+static int z2_count = 0;
+static int chip_count = 0;
+static int list_count = 0;
+static int current_device = -1;
 
 static DEFINE_SPINLOCK(z2ram_lock);
 
@@ -71,7 +70,7 @@ static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx *hctx,
 {
struct request *req = bd->rq;
unsigned long start = blk_rq_pos(req) << 9;
-   unsigned long len  = blk_rq_cur_bytes(req);
+   unsigned long len = blk_rq_cur_bytes(req);
 
blk_mq_start_request(req);
 
@@ -92,7 +91,7 @@ static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx *hctx,
 
if (len < size)
size = len;
-   addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ];
+   addr += z2ram_map[start >> Z2RAM_CHUNKSHIFT];
if (rq_data_dir(req) == READ)
memcpy(buffer, (char *)addr, size);
else
@@ -106,228 +105,214 @@ static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx 
*hctx,
return BLK_STS_OK;
 }
 
-static void
-get_z2ram( void )
+static void get_z2ram(void)
 {
-int i;
-
-for ( i = 0; i < Z2RAM_SIZE / Z2RAM_CHUNKSIZE; i++ )
-{
-   if ( test_bit( i, zorro_unused_z2ram ) )
-   {
-   z2_count++;
-   z2ram_map[z2ram_size++] = (unsigned long)ZTWO_VADDR(Z2RAM_START) +
- (i << Z2RAM_CHUNKSHIFT);
-   clear_bit( i, zorro_unused_z2ram );
+   int i;
+
+   for (i = 0; i < Z2RAM_SIZE / Z2RAM_CHUNKSIZE; i++) {
+   if (test_bit(i, zorro_unused_z2ram)) {
+   z2_count++;
+   z2ram_map[z2ram_size++] =
+   (unsigned long)ZTWO_VADDR(Z2RAM_START) +
+   (i << Z2RAM_CHUNKSHIFT);
+   clear_bit(i, zorro_unused_z2ram);
+   }
}
-}
 
-return;
+   return;
 }
 
-static void
-get_chipram( void )
+static void get_chipram(void)
 {
 
-while ( amiga_chip_avail() > ( Z2RAM_CHUNKSIZE * 4 ) )
-{
-   chip_count++;
-   z2ram_map[ z2ram_size ] =
-   (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE, "z2ram" );
+   while (amiga_chip_avail() > (Z2RAM_CHUNKSIZE * 4)) {
+   chip_count++;
+   z2ram_map[z2ram_size] =
+   (u_long) amiga_chip_alloc(Z2RAM_CHUNKSIZE, "z2ram");
 
-   if ( z2ram_map[ z2ram_size ] == 0 )
-   {
-   break;
+   if (z2ram_map[z2ram_size] == 0) {
+   break;
+   }
+
+   z2ram_size++;
}
 
-   z2ram_size++;
-}
-   
-return;
+   return;
 }
 
 static int z2_open(struct block_device *bdev, fmode_t mode)
 {
-int device;
-int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) *
-   sizeof( z2ram_map[0] );
-int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) *
-   sizeof( z2ram_map[0] );
-int rc = -ENOMEM;
-
-device = MINOR(bdev->bd_dev);
-
-mutex_lock(&z2ram_mutex);
-if ( current_device != -1 && current_device != device )
-{
-   rc = -EBUSY;
-   goto err_out;
-}
-
-if ( current_device == -1 )
-{
-   z2_count   = 0;
-   chip_count = 0;
-   list_count = 0;
-   z2ram_size = 0;
-
-   /* Use a specific list entry. */
-   if (device >= Z2MINOR_MEMLIST1 && device <= Z2MINOR_MEMLIST4) {
-   int index = device - Z2MINOR_MEMLIST1 + 1;
-   unsigned long size, paddr, vaddr;
-
-   if (index >= m68k_realnum_memory) {
-   printk( KERN_ERR DEVICE_NAME
-   ": no such entry in z2ram_map\n" );
-   goto err_out;
-   }
-
-   paddr = m68k_memory[index].addr;
-   size = m68k_memory[index

[PATCH 15/19] amiflop: use separate gendisks for Amiga vs MS-DOS mode

2020-09-03 Thread Christoph Hellwig
Use separate gendisks (which share a tag_set) for the native Amgiga vs
the MS-DOS mode instead of redirecting the gendisk lookup using a probe
callback.  This avoids potential problems with aliased block_device
instances and will eventually allow for removing the blk_register_region
framework.

Signed-off-by: Christoph Hellwig 
---
 drivers/block/amiflop.c | 98 +++--
 1 file changed, 55 insertions(+), 43 deletions(-)

diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 226219da3da6a7..de2bad8d1512f2 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -201,7 +201,7 @@ struct amiga_floppy_struct {
int busy;   /* true when drive is active */
int dirty;  /* true when trackbuf is not on disk */
int status; /* current error code for unit */
-   struct gendisk *gendisk;
+   struct gendisk *gendisk[2];
struct blk_mq_tag_set tag_set;
 };
 
@@ -1669,6 +1669,11 @@ static int floppy_open(struct block_device *bdev, 
fmode_t mode)
return -EBUSY;
}
 
+   if (unit[drive].type->code == FD_NODRIVE) {
+   mutex_unlock(&amiflop_mutex);
+   return -ENXIO;
+   }
+
if (mode & (FMODE_READ|FMODE_WRITE)) {
check_disk_change(bdev);
if (mode & FMODE_WRITE) {
@@ -1695,7 +1700,7 @@ static int floppy_open(struct block_device *bdev, fmode_t 
mode)
unit[drive].dtype=&data_types[system];
unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
data_types[system].sects*unit[drive].type->sect_mult;
-   set_capacity(unit[drive].gendisk, unit[drive].blocks);
+   set_capacity(unit[drive].gendisk[system], unit[drive].blocks);
 
printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,
   unit[drive].type->name, data_types[system].name);
@@ -1772,36 +1777,68 @@ static const struct blk_mq_ops amiflop_mq_ops = {
.queue_rq = amiflop_queue_rq,
 };
 
-static struct gendisk *fd_alloc_disk(int drive)
+static int fd_alloc_disk(int drive, int system)
 {
struct gendisk *disk;
 
disk = alloc_disk(1);
if (!disk)
goto out;
-
-   disk->queue = blk_mq_init_sq_queue(&unit[drive].tag_set, 
&amiflop_mq_ops,
-   2, BLK_MQ_F_SHOULD_MERGE);
-   if (IS_ERR(disk->queue)) {
-   disk->queue = NULL;
+   disk->queue = blk_mq_init_queue(&unit[drive].tag_set);
+   if (IS_ERR(disk->queue))
goto out_put_disk;
-   }
 
+   disk->major = FLOPPY_MAJOR;
+   disk->first_minor = drive + system;
+   disk->fops = &floppy_fops;
+   disk->events = DISK_EVENT_MEDIA_CHANGE;
+   if (system)
+   sprintf(disk->disk_name, "fd%d_msdos", drive);
+   else
+   sprintf(disk->disk_name, "fd%d", drive);
+   disk->private_data = &unit[drive];
+   set_capacity(disk, 880 * 2);
+
+   unit[drive].gendisk[system] = disk;
+   add_disk(disk);
+   return 0;
+
+out_put_disk:
+   disk->queue = NULL;
+   put_disk(disk);
+out:
+   return -ENOMEM;
+}
+
+static int fd_alloc_drive(int drive)
+{
unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL);
if (!unit[drive].trackbuf)
-   goto out_cleanup_queue;
+   goto out;
 
-   return disk;
+   memset(&unit[drive].tag_set, 0, sizeof(unit[drive].tag_set));
+   unit[drive].tag_set.ops = &amiflop_mq_ops;
+   unit[drive].tag_set.nr_hw_queues = 1;
+   unit[drive].tag_set.nr_maps = 1;
+   unit[drive].tag_set.queue_depth = 2;
+   unit[drive].tag_set.numa_node = NUMA_NO_NODE;
+   unit[drive].tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
+   if (blk_mq_alloc_tag_set(&unit[drive].tag_set))
+   goto out_cleanup_trackbuf;
 
-out_cleanup_queue:
-   blk_cleanup_queue(disk->queue);
-   disk->queue = NULL;
+   pr_cont(" fd%d", drive);
+
+   if (fd_alloc_disk(drive, 0) || fd_alloc_disk(drive, 1))
+   goto out_cleanup_tagset;
+   return 0;
+
+out_cleanup_tagset:
blk_mq_free_tag_set(&unit[drive].tag_set);
-out_put_disk:
-   put_disk(disk);
+out_cleanup_trackbuf:
+   kfree(unit[drive].trackbuf);
 out:
unit[drive].type->code = FD_NODRIVE;
-   return NULL;
+   return -ENOMEM;
 }
 
 static int __init fd_probe_drives(void)
@@ -1812,29 +1849,16 @@ static int __init fd_probe_drives(void)
drives=0;
nomem=0;
for(drive=0;drivecode == FD_NODRIVE)
continue;
 
-   disk = fd_alloc_disk(drive);
-   if (!disk) {
+   if (fd_alloc_drive(drive) < 0) {
pr_cont(" no mem for fd%d", drive);
nomem = 1;
continue;
}
-   u

[PATCH v5 13/80] drm/vc4: kms: Convert to for_each_new_crtc_state

2020-09-03 Thread Maxime Ripard
The vc4 atomic commit loop has an handrolled loop that is basically
identical to for_each_new_crtc_state, let's convert it to that helper.

Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_kms.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 210cc2408087..a41d105d4e3c 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -152,14 +152,16 @@ vc4_atomic_complete_commit(struct drm_atomic_state *state)
struct drm_device *dev = state->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_hvs *hvs = vc4->hvs;
-   struct vc4_crtc *vc4_crtc;
+   struct drm_crtc_state *new_crtc_state;
+   struct drm_crtc *crtc;
int i;
 
-   for (i = 0; i < dev->mode_config.num_crtc; i++) {
-   if (!state->crtcs[i].ptr || !state->crtcs[i].commit)
+   for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+   struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+
+   if (!new_crtc_state->commit)
continue;
 
-   vc4_crtc = to_vc4_crtc(state->crtcs[i].ptr);
vc4_hvs_mask_underrun(dev, vc4_crtc->channel);
}
 
-- 
git-series 0.9.1


[PATCH 02/19] block: merge drivers/base/map.c into block/genhd.c

2020-09-03 Thread Christoph Hellwig
Now that there is just a single user of the kobj_map functionality left,
merge it into the user to prepare for additional simplications.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Greg Kroah-Hartman 
---
 block/genhd.c| 130 +
 drivers/base/Makefile|   2 +-
 drivers/base/map.c   | 154 ---
 include/linux/kobj_map.h |  20 -
 4 files changed, 118 insertions(+), 188 deletions(-)
 delete mode 100644 drivers/base/map.c
 delete mode 100644 include/linux/kobj_map.h

diff --git a/block/genhd.c b/block/genhd.c
index 081f1039d9367f..44f69f4b2c5aa6 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -29,6 +28,16 @@
 static DEFINE_MUTEX(block_class_lock);
 static struct kobject *block_depr;
 
+struct bdev_map {
+   struct bdev_map *next;
+   dev_t dev;
+   unsigned long range;
+   struct module *owner;
+   struct kobject *(*probe)(dev_t, int *, void *);
+   int (*lock)(dev_t, void *);
+   void *data;
+} *bdev_map[255];
+
 /* for extended dynamic devt allocation, currently only one major is used */
 #define NR_EXT_DEVT(1 << MINORBITS)
 
@@ -517,8 +526,6 @@ void unregister_blkdev(unsigned int major, const char *name)
 
 EXPORT_SYMBOL(unregister_blkdev);
 
-static struct kobj_map *bdev_map;
-
 /**
  * blk_mangle_minor - scatter minor numbers apart
  * @minor: minor number to mangle
@@ -645,16 +652,60 @@ void blk_register_region(dev_t devt, unsigned long range, 
struct module *module,
 struct kobject *(*probe)(dev_t, int *, void *),
 int (*lock)(dev_t, void *), void *data)
 {
-   kobj_map(bdev_map, devt, range, module, probe, lock, data);
-}
+   unsigned n = MAJOR(devt + range - 1) - MAJOR(devt) + 1;
+   unsigned index = MAJOR(devt);
+   unsigned i;
+   struct bdev_map *p;
+
+   n = min(n, 255u);
+   p = kmalloc_array(n, sizeof(struct bdev_map), GFP_KERNEL);
+   if (p == NULL)
+   return;
 
+   for (i = 0; i < n; i++, p++) {
+   p->owner = module;
+   p->probe = probe;
+   p->lock = lock;
+   p->dev = devt;
+   p->range = range;
+   p->data = data;
+   }
+
+   mutex_lock(&block_class_lock);
+   for (i = 0, p -= n; i < n; i++, p++, index++) {
+   struct bdev_map **s = &bdev_map[index % 255];
+   while (*s && (*s)->range < range)
+   s = &(*s)->next;
+   p->next = *s;
+   *s = p;
+   }
+   mutex_unlock(&block_class_lock);
+}
 EXPORT_SYMBOL(blk_register_region);
 
 void blk_unregister_region(dev_t devt, unsigned long range)
 {
-   kobj_unmap(bdev_map, devt, range);
-}
+   unsigned n = MAJOR(devt + range - 1) - MAJOR(devt) + 1;
+   unsigned index = MAJOR(devt);
+   unsigned i;
+   struct bdev_map *found = NULL;
 
+   mutex_lock(&block_class_lock);
+   for (i = 0; i < min(n, 255u); i++, index++) {
+   struct bdev_map **s;
+   for (s = &bdev_map[index % 255]; *s; s = &(*s)->next) {
+   struct bdev_map *p = *s;
+   if (p->dev == devt && p->range == range) {
+   *s = p->next;
+   if (!found)
+   found = p;
+   break;
+   }
+   }
+   }
+   mutex_unlock(&block_class_lock);
+   kfree(found);
+}
 EXPORT_SYMBOL(blk_unregister_region);
 
 static struct kobject *exact_match(dev_t devt, int *partno, void *data)
@@ -980,6 +1031,47 @@ static ssize_t disk_badblocks_store(struct device *dev,
return badblocks_store(disk->bb, page, len, 0);
 }
 
+static struct gendisk *lookup_gendisk(dev_t dev, int *partno)
+{
+   struct kobject *kobj;
+   struct bdev_map *p;
+   unsigned long best = ~0UL;
+
+retry:
+   mutex_lock(&block_class_lock);
+   for (p = bdev_map[MAJOR(dev) % 255]; p; p = p->next) {
+   struct kobject *(*probe)(dev_t, int *, void *);
+   struct module *owner;
+   void *data;
+
+   if (p->dev > dev || p->dev + p->range - 1 < dev)
+   continue;
+   if (p->range - 1 >= best)
+   break;
+   if (!try_module_get(p->owner))
+   continue;
+   owner = p->owner;
+   data = p->data;
+   probe = p->probe;
+   best = p->range - 1;
+   *partno = dev - p->dev;
+   if (p->lock && p->lock(dev, data) < 0) {
+   module_put(owner);
+   continue;
+   }
+   mutex_unlock(&block_class_lock);
+   kobj = probe(dev, partno, data);
+ 

[PATCH 01/19] char_dev: replace cdev_map with an xarray

2020-09-03 Thread Christoph Hellwig
None of the complicated overlapping regions bits of the kobj_map are
required for the character device lookup, so just a trivial xarray
instead.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Greg Kroah-Hartman 
---
 fs/char_dev.c | 94 +--
 fs/dcache.c   |  1 -
 fs/internal.h |  5 ---
 3 files changed, 47 insertions(+), 53 deletions(-)

diff --git a/fs/char_dev.c b/fs/char_dev.c
index ba0ded7842a779..f9a983d2d1a975 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -17,7 +17,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -25,8 +24,7 @@
 
 #include "internal.h"
 
-static struct kobj_map *cdev_map;
-
+static DEFINE_XARRAY(cdev_map);
 static DEFINE_MUTEX(chrdevs_lock);
 
 #define CHRDEV_MAJOR_HASH_SIZE 255
@@ -367,6 +365,29 @@ void cdev_put(struct cdev *p)
}
 }
 
+static struct cdev *cdev_lookup(dev_t dev)
+{
+   struct cdev *cdev;
+
+retry:
+   mutex_lock(&chrdevs_lock);
+   cdev = xa_load(&cdev_map, dev);
+   if (!cdev) {
+   mutex_unlock(&chrdevs_lock);
+
+   if (request_module("char-major-%d-%d",
+  MAJOR(dev), MINOR(dev)) > 0)
+   /* Make old-style 2.4 aliases work */
+   request_module("char-major-%d", MAJOR(dev));
+   goto retry;
+   }
+
+   if (!cdev_get(cdev))
+   cdev = NULL;
+   mutex_unlock(&chrdevs_lock);
+   return cdev;
+}
+
 /*
  * Called every time a character special file is opened
  */
@@ -380,13 +401,10 @@ static int chrdev_open(struct inode *inode, struct file 
*filp)
spin_lock(&cdev_lock);
p = inode->i_cdev;
if (!p) {
-   struct kobject *kobj;
-   int idx;
spin_unlock(&cdev_lock);
-   kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
-   if (!kobj)
+   new = cdev_lookup(inode->i_rdev);
+   if (!new)
return -ENXIO;
-   new = container_of(kobj, struct cdev, kobj);
spin_lock(&cdev_lock);
/* Check i_cdev again in case somebody beat us to it while
   we dropped the lock. */
@@ -454,18 +472,6 @@ const struct file_operations def_chr_fops = {
.llseek = noop_llseek,
 };
 
-static struct kobject *exact_match(dev_t dev, int *part, void *data)
-{
-   struct cdev *p = data;
-   return &p->kobj;
-}
-
-static int exact_lock(dev_t dev, void *data)
-{
-   struct cdev *p = data;
-   return cdev_get(p) ? 0 : -1;
-}
-
 /**
  * cdev_add() - add a char device to the system
  * @p: the cdev structure for the device
@@ -478,7 +484,7 @@ static int exact_lock(dev_t dev, void *data)
  */
 int cdev_add(struct cdev *p, dev_t dev, unsigned count)
 {
-   int error;
+   int error, i;
 
p->dev = dev;
p->count = count;
@@ -486,14 +492,22 @@ int cdev_add(struct cdev *p, dev_t dev, unsigned count)
if (WARN_ON(dev == WHITEOUT_DEV))
return -EBUSY;
 
-   error = kobj_map(cdev_map, dev, count, NULL,
-exact_match, exact_lock, p);
-   if (error)
-   return error;
+   mutex_lock(&chrdevs_lock);
+   for (i = 0; i < count; i++) {
+   error = xa_insert(&cdev_map, dev + i, p, GFP_KERNEL);
+   if (error)
+   goto out_unwind;
+   }
+   mutex_unlock(&chrdevs_lock);
 
kobject_get(p->kobj.parent);
-
return 0;
+
+out_unwind:
+   while (--i >= 0)
+   xa_erase(&cdev_map, dev + i);
+   mutex_unlock(&chrdevs_lock);
+   return error;
 }
 
 /**
@@ -575,11 +589,6 @@ void cdev_device_del(struct cdev *cdev, struct device *dev)
cdev_del(cdev);
 }
 
-static void cdev_unmap(dev_t dev, unsigned count)
-{
-   kobj_unmap(cdev_map, dev, count);
-}
-
 /**
  * cdev_del() - remove a cdev from the system
  * @p: the cdev structure to be removed
@@ -593,11 +602,16 @@ static void cdev_unmap(dev_t dev, unsigned count)
  */
 void cdev_del(struct cdev *p)
 {
-   cdev_unmap(p->dev, p->count);
+   int i;
+
+   mutex_lock(&chrdevs_lock);
+   for (i = 0; i < p->count; i++)
+   xa_erase(&cdev_map, p->dev + i);
+   mutex_unlock(&chrdevs_lock);
+
kobject_put(&p->kobj);
 }
 
-
 static void cdev_default_release(struct kobject *kobj)
 {
struct cdev *p = container_of(kobj, struct cdev, kobj);
@@ -656,20 +670,6 @@ void cdev_init(struct cdev *cdev, const struct 
file_operations *fops)
cdev->ops = fops;
 }
 
-static struct kobject *base_probe(dev_t dev, int *part, void *data)
-{
-   if (request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0)
-   /* Make old-style 2.4 aliases work */
-   request_module("char-major-%d", MAJOR(dev));
-   return NULL;
-}
-
-void __init chrdev_init(void)
-{
-   cdev_map = kobj_map_init(base_pro

[PATCH 19/19] block: switch gendisk lookup to a simple xarray

2020-09-03 Thread Christoph Hellwig
Now that bdev_map is only used for finding gendisks, we can use
a simple xarray instead of the regions tracking structure for it.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Greg Kroah-Hartman 
---
 block/genhd.c | 208 --
 include/linux/genhd.h |   7 --
 2 files changed, 37 insertions(+), 178 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 3abd764443a6af..6e0789a158f579 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -27,15 +27,7 @@
 
 static struct kobject *block_depr;
 
-struct bdev_map {
-   struct bdev_map *next;
-   dev_t dev;
-   unsigned long range;
-   struct module *owner;
-   struct kobject *(*probe)(dev_t, int *, void *);
-   int (*lock)(dev_t, void *);
-   void *data;
-} *bdev_map[255];
+static DEFINE_XARRAY(bdev_map);
 static DEFINE_MUTEX(bdev_map_lock);
 
 /* for extended dynamic devt allocation, currently only one major is used */
@@ -646,85 +638,26 @@ static char *bdevt_str(dev_t devt, char *buf)
return buf;
 }
 
-/*
- * Register device numbers dev..(dev+range-1)
- * range must be nonzero
- * The hash chain is sorted on range, so that subranges can override.
- */
-void blk_register_region(dev_t devt, unsigned long range, struct module 
*module,
-struct kobject *(*probe)(dev_t, int *, void *),
-int (*lock)(dev_t, void *), void *data)
-{
-   unsigned n = MAJOR(devt + range - 1) - MAJOR(devt) + 1;
-   unsigned index = MAJOR(devt);
-   unsigned i;
-   struct bdev_map *p;
-
-   n = min(n, 255u);
-   p = kmalloc_array(n, sizeof(struct bdev_map), GFP_KERNEL);
-   if (p == NULL)
-   return;
-
-   for (i = 0; i < n; i++, p++) {
-   p->owner = module;
-   p->probe = probe;
-   p->lock = lock;
-   p->dev = devt;
-   p->range = range;
-   p->data = data;
-   }
+static void blk_register_region(struct gendisk *disk)
+{
+   int i;
 
mutex_lock(&bdev_map_lock);
-   for (i = 0, p -= n; i < n; i++, p++, index++) {
-   struct bdev_map **s = &bdev_map[index % 255];
-   while (*s && (*s)->range < range)
-   s = &(*s)->next;
-   p->next = *s;
-   *s = p;
+   for (i = 0; i < disk->minors; i++) {
+   if (xa_insert(&bdev_map, disk_devt(disk) + i, disk, GFP_KERNEL))
+   WARN_ON_ONCE(1);
}
mutex_unlock(&bdev_map_lock);
 }
-EXPORT_SYMBOL(blk_register_region);
 
-void blk_unregister_region(dev_t devt, unsigned long range)
+static void blk_unregister_region(struct gendisk *disk)
 {
-   unsigned n = MAJOR(devt + range - 1) - MAJOR(devt) + 1;
-   unsigned index = MAJOR(devt);
-   unsigned i;
-   struct bdev_map *found = NULL;
+   int i;
 
mutex_lock(&bdev_map_lock);
-   for (i = 0; i < min(n, 255u); i++, index++) {
-   struct bdev_map **s;
-   for (s = &bdev_map[index % 255]; *s; s = &(*s)->next) {
-   struct bdev_map *p = *s;
-   if (p->dev == devt && p->range == range) {
-   *s = p->next;
-   if (!found)
-   found = p;
-   break;
-   }
-   }
-   }
+   for (i = 0; i < disk->minors; i++)
+   xa_erase(&bdev_map, disk_devt(disk) + i);
mutex_unlock(&bdev_map_lock);
-   kfree(found);
-}
-EXPORT_SYMBOL(blk_unregister_region);
-
-static struct kobject *exact_match(dev_t devt, int *partno, void *data)
-{
-   struct gendisk *p = data;
-
-   return &disk_to_dev(p)->kobj;
-}
-
-static int exact_lock(dev_t devt, void *data)
-{
-   struct gendisk *p = data;
-
-   if (!get_disk_and_module(p))
-   return -1;
-   return 0;
 }
 
 static void register_disk(struct device *parent, struct gendisk *disk,
@@ -875,8 +808,7 @@ static void __device_add_disk(struct device *parent, struct 
gendisk *disk,
ret = bdi_register(bdi, "%u:%u", MAJOR(devt), MINOR(devt));
WARN_ON(ret);
bdi_set_owner(bdi, dev);
-   blk_register_region(disk_devt(disk), disk->minors, NULL,
-   exact_match, exact_lock, disk);
+   blk_register_region(disk);
}
register_disk(parent, disk, groups);
if (register_queue)
@@ -989,7 +921,7 @@ void del_gendisk(struct gendisk *disk)
blk_unregister_queue(disk);

if (!(disk->flags & GENHD_FL_HIDDEN))
-   blk_unregister_region(disk_devt(disk), disk->minors);
+   blk_unregister_region(disk);
/*
 * Remove gendisk pointer from idr so that it cannot be looked up
 * while RCU period before freeing gendisk is running to prevent
@@ -1055,54 +987

[PATCH v5 07/80] drm/vc4: crtc: Deal with different number of pixel per clock

2020-09-03 Thread Maxime Ripard
Some of the HDMI pixelvalves in vc5 output two pixels per clock cycle.
Let's put the number of pixel output per clock cycle in the CRTC data and
update the various calculations to reflect that.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 18 +++---
 drivers/gpu/drm/vc4/vc4_drv.h  |  3 +++
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 6d8fa6118fc1..e55b2208b4b7 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -235,6 +235,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+   const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
struct drm_crtc_state *state = crtc->state;
struct drm_display_mode *mode = &state->adjusted_mode;
bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -242,6 +243,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
   vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
+   u8 ppc = pv_data->pixels_per_clock;
 
/* Reset the PV fifo. */
CRTC_WRITE(PV_CONTROL, 0);
@@ -249,17 +251,16 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc)
CRTC_WRITE(PV_CONTROL, 0);
 
CRTC_WRITE(PV_HORZA,
-  VC4_SET_FIELD((mode->htotal -
- mode->hsync_end) * pixel_rep,
+  VC4_SET_FIELD((mode->htotal - mode->hsync_end) * pixel_rep / 
ppc,
 PV_HORZA_HBP) |
-  VC4_SET_FIELD((mode->hsync_end -
- mode->hsync_start) * pixel_rep,
+  VC4_SET_FIELD((mode->hsync_end - mode->hsync_start) * 
pixel_rep / ppc,
 PV_HORZA_HSYNC));
+
CRTC_WRITE(PV_HORZB,
-  VC4_SET_FIELD((mode->hsync_start -
- mode->hdisplay) * pixel_rep,
+  VC4_SET_FIELD((mode->hsync_start - mode->hdisplay) * 
pixel_rep / ppc,
 PV_HORZB_HFP) |
-  VC4_SET_FIELD(mode->hdisplay * pixel_rep, PV_HORZB_HACTIVE));
+  VC4_SET_FIELD(mode->hdisplay * pixel_rep / ppc,
+PV_HORZB_HACTIVE));
 
CRTC_WRITE(PV_VERTA,
   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
@@ -761,6 +762,7 @@ static const struct vc4_pv_data bcm2835_pv0_data = {
.hvs_channel = 0,
},
.debugfs_name = "crtc0_regs",
+   .pixels_per_clock = 1,
.encoder_types = {
[PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
[PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
@@ -772,6 +774,7 @@ static const struct vc4_pv_data bcm2835_pv1_data = {
.hvs_channel = 2,
},
.debugfs_name = "crtc1_regs",
+   .pixels_per_clock = 1,
.encoder_types = {
[PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
[PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
@@ -783,6 +786,7 @@ static const struct vc4_pv_data bcm2835_pv2_data = {
.hvs_channel = 1,
},
.debugfs_name = "crtc2_regs",
+   .pixels_per_clock = 1,
.encoder_types = {
[PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI,
[PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 6358f6ca8d56..0bc150daafb2 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -454,6 +454,9 @@ struct vc4_crtc_data {
 struct vc4_pv_data {
struct vc4_crtc_database;
 
+   /* Number of pixels output per clock period */
+   u8 pixels_per_clock;
+
enum vc4_encoder_type encoder_types[4];
const char *debugfs_name;
 
-- 
git-series 0.9.1


[PATCH v5 01/80] dt-bindings: display: Add support for the BCM2711 HVS

2020-09-03 Thread Maxime Ripard
The HVS found in the BCM2711 is slightly different from the previous
generations, let's add a compatible for it.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml | 18 ++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml 
b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
index 02410f8d6d49..e826ab0adb75 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hvs.yaml
@@ -11,7 +11,9 @@ maintainers:
 
 properties:
   compatible:
-const: brcm,bcm2835-hvs
+enum:
+  - brcm,bcm2711-hvs
+  - brcm,bcm2835-hvs
 
   reg:
 maxItems: 1
@@ -19,6 +21,10 @@ properties:
   interrupts:
 maxItems: 1
 
+  clocks:
+maxItems: 1
+description: Core Clock
+
 required:
   - compatible
   - reg
@@ -26,6 +32,16 @@ required:
 
 additionalProperties: false
 
+if:
+  properties:
+compatible:
+  contains:
+const: brcm,bcm2711-hvs"
+
+then:
+  required:
+- clocks
+
 examples:
   - |
 hvs@7e40 {
-- 
git-series 0.9.1


[PATCH v5 05/80] drm/vc4: plane: Optimize the LBM allocation size

2020-09-03 Thread Maxime Ripard
From: Dave Stevenson 

The current code is using the maximum of the source line size and the
destination line size to compute the size of the LBM to allocate.

While this is simpler, it starts to be an issue with modes such as 4k with
a quite long that will consume all the available memory, so we no longer
have that luxury.

Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Dave Stevenson 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_plane.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index d0771ebd5f75..23916814b4e3 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -437,10 +437,7 @@ static void vc4_write_ppf(struct vc4_plane_state 
*vc4_state, u32 src, u32 dst)
 static u32 vc4_lbm_size(struct drm_plane_state *state)
 {
struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
-   /* This is the worst case number.  One of the two sizes will
-* be used depending on the scaling configuration.
-*/
-   u32 pix_per_line = max(vc4_state->src_w[0], (u32)vc4_state->crtc_w);
+   u32 pix_per_line;
u32 lbm;
 
/* LBM is not needed when there's no vertical scaling. */
@@ -448,6 +445,18 @@ static u32 vc4_lbm_size(struct drm_plane_state *state)
vc4_state->y_scaling[1] == VC4_SCALING_NONE)
return 0;
 
+   /*
+* This can be further optimized in the RGB/YUV444 case if the PPF
+* decimation factor is between 0.5 and 1.0 by using crtc_w.
+*
+* It's not an issue though, since in that case since src_w[0] is going
+* to be greater than or equal to crtc_w.
+*/
+   if (vc4_state->x_scaling[0] == VC4_SCALING_TPZ)
+   pix_per_line = vc4_state->crtc_w;
+   else
+   pix_per_line = vc4_state->src_w[0];
+
if (!vc4_state->is_yuv) {
if (vc4_state->y_scaling[0] == VC4_SCALING_TPZ)
lbm = pix_per_line * 8;
-- 
git-series 0.9.1


[PATCH v5 00/80] drm/vc4: Support BCM2711 Display Pipeline

2020-09-03 Thread Maxime Ripard
Hi everyone,

Here's a (pretty long) series to introduce support in the VC4 DRM driver
for the display pipeline found in the BCM2711 (and thus the RaspberryPi 4).

The main differences are that there's two HDMI controllers and that there's
more pixelvalve now. Those pixelvalve come with a mux in the HVS that still
have only 3 FIFOs. Both of those differences are breaking a bunch of
expectations in the driver, so we first need a good bunch of cleanup and
reworks to introduce support for the new controllers.

Similarly, the HDMI controller has all its registers shuffled and split in
multiple controllers now, so we need a bunch of changes to support this as
well.

Only the HDMI support is enabled for now (even though the DPI and DSI
outputs have been tested too).

Let me know if you have any comments
Maxime

Cc: bcm-kernel-feedback-l...@broadcom.com
Cc: devicet...@vger.kernel.org
Cc: Kamal Dasu 
Cc: Philipp Zabel 
Cc: Rob Herring 
Cc: Stephen Boyd 

Changes from v4:
  - Rebased on top of next-20200828
  - Collected the various tags
  - Fixed some issues with 4k support and dual output (thanks Hoegeun!)
  - Fixed typos in commit logs (thanks Dave!)
  - Split the csc setup hook into its own patch again
  - Added the CEC clock to the DT binding
  - Fixed the DT binding example
  - Reduced the number of calls to of_device_is_compatible in vc4_kms_load
  - Added back the check for the state commit in our commit hook

Changes from v3:
  - Rebased on top of next-20200708
  - Added a name to the HDMI audio codec component
  - Only disable the BCM2711 HDMI pixelvalves at boot
  - Fixed an error in the HVS binding
  - Fix a framebuffer size condition that was inverted
  - Changed the channel allocation algorithm using Eric's suggestion
  - Always write the muxing values instead of updating if needed
  - Improved a bit the hvs_available_channels comment in the structure
  - Change atomic_complete_commit code to use for_each_new_crtc_in_state
  - Change the muxing code to take into account disparities between the
BCM2711 and previous SoCs.
  - Only change the clock rate on BCM2711 during a modeset
  - Fix a crash at atomic_disable
  - Use clk_set_min_rate for the core clock too
  - Add a few defines, and simplify the FIFO level stuff
  - Reordered the patches according to Eric's reviews
  - Fixed a regression with VID_CTL setting on RPI3

Changes from v2:
  - Rebased on top of next-20200526
  - Split the firmware clock series away
  - Removed the stuck pixel (with all the subsequent pixels being shifted
by one
  - Fixed the writeback issue too.
  - Fix the dual output
  - Fixed the return value of phy_get_cp_current
  - Enhanced the comment on the reset delay
  - Increase the max width and height
  - Made a proper Kconfig option for the DVP clock driver
  - Fixed the alsa card name collision

Changes from v1:
  - Rebased on top of 5.7-rc1
  - Run checkpatch
  - Added audio support
  - Fixed some HDMI timeouts
  - Swiched to clk_hw_register_gate_parent_data
  - Reorder Kconfig symbols in drivers/i2c/busses
  - Make the firmware clocks a child of the firmware node
  - Switch DVP clock driver to clk_hw interface
  - constify raspberrypi_clk_data in raspberrypi_clock_property
  - Don't mark firmware clocks as IGNORE_UNUSED
  - Change from reset_ms to reset_us in reset-simple, and add a bit more
comments
  - Remove generic clk patch to test if a NULL pointer is returned
  - Removed misleading message in the is_prepared renaming patch commit
message
  - Constify HDMI controller variants
  - Fix a bug in the allocation size of the clk data array
  - Added a mention in the DT binding conversion patches about the breakage
  - Merged a few fixes from kbuild
  - Fixed a few bisection and CEC build issues
  - Collected Acked-by and Reviewed-by
  - Change Dave email address to raspberrypi.com

Dave Stevenson (7):
  drm/vc4: Add support for the BCM2711 HVS5
  drm/vc4: plane: Change LBM alignment constraint on LBM
  drm/vc4: plane: Optimize the LBM allocation size
  drm/vc4: hdmi: Use reg-names to retrieve the HDMI audio registers
  drm/vc4: hdmi: Reset audio infoframe on encoder_enable if previously streaming
  drm/vc4: hdmi: Set the b-frame marker to the match ALSA's default.
  drm/vc4: hdmi: Add audio-related callbacks

Hoegeun Kwon (1):
  drm/vc4: hdmi: Add pixel BVB clock control

Maxime Ripard (72):
  dt-bindings: display: Add support for the BCM2711 HVS
  drm/vc4: hvs: Boost the core clock during modeset
  drm/vc4: plane: Create more planes
  drm/vc4: crtc: Deal with different number of pixel per clock
  drm/vc4: crtc: Use a shared interrupt
  drm/vc4: crtc: Move the cob allocation outside of bind
  drm/vc4: crtc: Rename HVS channel to output
  drm/vc4: crtc: Use local chan variable
  drm/vc4: crtc: Enable and disable the PV in atomic_enable / disable
  drm/vc4: kms: Convert to for_each_new_crtc_state
  drm/vc4: crtc: Assign output to channel automatically
  drm/vc4: crtc: Add FIFO depth to vc4_crtc_data
  drm/vc

[PATCH v5 08/80] drm/vc4: crtc: Use a shared interrupt

2020-09-03 Thread Maxime Ripard
Some pixelvalves in vc5 use the same interrupt line so let's register our
interrupt handler as a shared one.

Reviewed-by: Eric Anholt 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index e55b2208b4b7..9faae22cb0f8 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -919,7 +919,9 @@ static int vc4_crtc_bind(struct device *dev, struct device 
*master, void *data)
CRTC_WRITE(PV_INTEN, 0);
CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
-  vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
+  vc4_crtc_irq_handler,
+  IRQF_SHARED,
+  "vc4 crtc", vc4_crtc);
if (ret)
goto err_destroy_planes;
 
-- 
git-series 0.9.1


[PATCH v5 10/80] drm/vc4: crtc: Rename HVS channel to output

2020-09-03 Thread Maxime Ripard
In vc5, the HVS has 6 outputs and 3 FIFOs (or channels), with
pixelvalves each being assigned to a given output, but each output can
then be muxed to feed from multiple FIFOs.

Since vc4 had that entirely static, both were probably equivalent, but
since that changes, let's rename hvs_channel to hvs_output in the
vc4_crtc_data, since a pixelvalve is really connected to an output, and
not to a FIFO.

Reviewed-by: Dave Stevenson 
Tested-by: Chanwoo Choi 
Tested-by: Hoegeun Kwon 
Tested-by: Stefan Wahren 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 8 
 drivers/gpu/drm/vc4/vc4_drv.h  | 4 ++--
 drivers/gpu/drm/vc4/vc4_hvs.c  | 2 +-
 drivers/gpu/drm/vc4/vc4_txp.c  | 2 +-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index fdecaba77836..d3126fe04d9a 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -775,7 +775,7 @@ static const struct drm_crtc_helper_funcs 
vc4_crtc_helper_funcs = {
 
 static const struct vc4_pv_data bcm2835_pv0_data = {
.base = {
-   .hvs_channel = 0,
+   .hvs_output = 0,
},
.debugfs_name = "crtc0_regs",
.pixels_per_clock = 1,
@@ -787,7 +787,7 @@ static const struct vc4_pv_data bcm2835_pv0_data = {
 
 static const struct vc4_pv_data bcm2835_pv1_data = {
.base = {
-   .hvs_channel = 2,
+   .hvs_output = 2,
},
.debugfs_name = "crtc1_regs",
.pixels_per_clock = 1,
@@ -799,7 +799,7 @@ static const struct vc4_pv_data bcm2835_pv1_data = {
 
 static const struct vc4_pv_data bcm2835_pv2_data = {
.base = {
-   .hvs_channel = 1,
+   .hvs_output = 1,
},
.debugfs_name = "crtc2_regs",
.pixels_per_clock = 1,
@@ -862,7 +862,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
*vc4_crtc,
drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
  crtc_funcs, NULL);
drm_crtc_helper_add(crtc, crtc_helper_funcs);
-   vc4_crtc->channel = vc4_crtc->data->hvs_channel;
+   vc4_crtc->channel = vc4_crtc->data->hvs_output;
drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
 
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index d80fc3bbb450..d1cf4c038180 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -447,8 +447,8 @@ to_vc4_encoder(struct drm_encoder *encoder)
 }
 
 struct vc4_crtc_data {
-   /* Which channel of the HVS this pixelvalve sources from. */
-   int hvs_channel;
+   /* Which output of the HVS this pixelvalve sources from. */
+   int hvs_output;
 };
 
 struct vc4_pv_data {
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index abdb43c4cc10..365425d67f3f 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -419,7 +419,7 @@ void vc4_hvs_mode_set_nofb(struct drm_crtc *crtc)
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
 
-   if (vc4_crtc->data->hvs_channel == 2) {
+   if (vc4_crtc->data->hvs_output == 2) {
u32 dispctrl;
u32 dsp3_mux;
 
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index a7c3af0005a0..f39d9900d027 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -452,7 +452,7 @@ static irqreturn_t vc4_txp_interrupt(int irq, void *data)
 }
 
 static const struct vc4_crtc_data vc4_txp_crtc_data = {
-   .hvs_channel = 2,
+   .hvs_output = 2,
 };
 
 static int vc4_txp_bind(struct device *dev, struct device *master, void *data)
-- 
git-series 0.9.1


Re: [PATCH] sh: fix syscall tracing

2020-09-03 Thread John Paul Adrian Glaubitz
Hi Rich!

On 9/3/20 7:48 AM, Rich Felker wrote:
> Addition of SECCOMP_FILTER exposed a longstanding bug in
> do_syscall_trace_enter, whereby r0 (the 5th argument register) was
> mistakenly used where r3 (syscall_nr) was intended. By overwriting r0
> rather than r3 with -1 when attempting to block a syscall, the
> existing code would instead have caused the syscall to execute with an
> argument clobbered.
> 
> Commit 0bb605c2c7f2b4b3 then introduced skipping of the syscall when
> do_syscall_trace_enter returns -1, so that the return value set by
> seccomp filters would not be clobbered by -ENOSYS. This eliminated the
> clobbering of the 5th argument register, but instead caused syscalls
> made with a 5th argument of -1 to be misinterpreted as a request by
> do_syscall_trace_enter to suppress the syscall.
> 
> Fixes: 0bb605c2c7f2b4b3 ("sh: Add SECCOMP_FILTER")
> Fixes: ab99c733ae73cce3 ("sh: Make syscall tracer use tracehook notifiers, 
> add TIF_NOTIFY_RESUME.")
> Signed-off-by: Rich Felker 

I'm testing this patch now with a rebased kernel and a rebased libseccomp with 
my
patch for SuperH support on top.

I'll report back later.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaub...@debian.org
`. `'   Freie Universitaet Berlin - glaub...@physik.fu-berlin.de
  `-GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


[PATCH 13/19] ide: switch to __register_blkdev for command set probing

2020-09-03 Thread Christoph Hellwig
ide is the last user of the blk_register_region framework except for the
tracking of allocated gendisk.  Switch to __register_blkdev, even if that
doesn't allow us to trivially find out which command set to probe for.
That means we now always request all modules when a user tries to access
an unclaimed ide device node, but except for a few potentially loaded
modules for a fringe use case of a deprecated and soon to be removed
driver that doesn't make a difference.

Signed-off-by: Christoph Hellwig 
---
 drivers/ide/ide-probe.c | 34 ++
 1 file changed, 6 insertions(+), 28 deletions(-)

diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 076d34b381720f..1c1567bb519429 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -902,31 +902,12 @@ static int init_irq (ide_hwif_t *hwif)
return 1;
 }
 
-static int ata_lock(dev_t dev, void *data)
+static void ata_probe(dev_t dev)
 {
-   /* FIXME: we want to pin hwif down */
-   return 0;
-}
-
-static struct kobject *ata_probe(dev_t dev, int *part, void *data)
-{
-   ide_hwif_t *hwif = data;
-   int unit = *part >> PARTN_BITS;
-   ide_drive_t *drive = hwif->devices[unit];
-
-   if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
-   return NULL;
-
-   if (drive->media == ide_disk)
-   request_module("ide-disk");
-   if (drive->media == ide_cdrom || drive->media == ide_optical)
-   request_module("ide-cd");
-   if (drive->media == ide_tape)
-   request_module("ide-tape");
-   if (drive->media == ide_floppy)
-   request_module("ide-floppy");
-
-   return NULL;
+   request_module("ide-disk");
+   request_module("ide-cd");
+   request_module("ide-tape");
+   request_module("ide-floppy");
 }
 
 void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
@@ -967,7 +948,7 @@ static int hwif_init(ide_hwif_t *hwif)
return 0;
}
 
-   if (register_blkdev(hwif->major, hwif->name))
+   if (__register_blkdev(hwif->major, hwif->name, ata_probe))
return 0;
 
if (!hwif->sg_max_nents)
@@ -989,8 +970,6 @@ static int hwif_init(ide_hwif_t *hwif)
goto out;
}
 
-   blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
-   THIS_MODULE, ata_probe, ata_lock, hwif);
return 1;
 
 out:
@@ -1582,7 +1561,6 @@ static void ide_unregister(ide_hwif_t *hwif)
/*
 * Remove us from the kernel's knowledge
 */
-   blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVESmajor, hwif->name);
 
-- 
2.28.0



[PATCH 12/19] md: use __register_blkdev to allocate devices on demand

2020-09-03 Thread Christoph Hellwig
Use the simpler mechanism attached to major_name to allocate a brd device
when a currently unregistered minor is accessed.

Signed-off-by: Christoph Hellwig 
Acked-by: Song Liu 
---
 drivers/md/md.c | 21 -
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9562ef598ae1f4..be3625acf67d7e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5766,11 +5766,12 @@ static int md_alloc(dev_t dev, char *name)
return error;
 }
 
-static struct kobject *md_probe(dev_t dev, int *part, void *data)
+static void md_probe(dev_t dev)
 {
+   if (MAJOR(dev) == MD_MAJOR && MINOR(dev) >= 512)
+   return;
if (create_on_open)
md_alloc(dev, NULL);
-   return NULL;
 }
 
 static int add_named_array(const char *val, const struct kernel_param *kp)
@@ -6536,7 +6537,7 @@ static void autorun_devices(int part)
break;
}
 
-   md_probe(dev, NULL, NULL);
+   md_probe(dev);
mddev = mddev_find(dev);
if (!mddev || !mddev->gendisk) {
if (mddev)
@@ -9548,18 +9549,15 @@ static int __init md_init(void)
if (!md_misc_wq)
goto err_rdev_misc_wq;
 
-   if ((ret = register_blkdev(MD_MAJOR, "md")) < 0)
+   ret = __register_blkdev(MD_MAJOR, "md", md_probe);
+   if (ret < 0)
goto err_md;
 
-   if ((ret = register_blkdev(0, "mdp")) < 0)
+   ret = __register_blkdev(0, "mdp", md_probe);
+   if (ret < 0)
goto err_mdp;
mdp_major = ret;
 
-   blk_register_region(MKDEV(MD_MAJOR, 0), 512, THIS_MODULE,
-   md_probe, NULL, NULL);
-   blk_register_region(MKDEV(mdp_major, 0), 1UL<

[PATCH 14/19] floppy: use a separate gendisk for each media format

2020-09-03 Thread Christoph Hellwig
The floppy driver usually autodetects the media when used with the
normal /dev/fd? devices, which also are the only nodes created by udev.
But it also supports various aliases that force a given media format.
That is currently supported using the blk_register_region framework
which finds the floppy gendisk even for a 'mismatched' dev_t.  The
problem with this (besides the code complexity) is that it creates
multiple struct block_device instances for the whole device of a
single gendisk, which can lead to interesting issues in code not
aware of that fact.

To fix this just create a separate gendisk for each of the aliases
if they are accessed.

Signed-off-by: Christoph Hellwig 
---
 drivers/block/floppy.c | 154 ++---
 1 file changed, 97 insertions(+), 57 deletions(-)

diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index a563b023458a8b..f07d97558cb698 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -402,7 +402,6 @@ static struct floppy_drive_params drive_params[N_DRIVE];
 static struct floppy_drive_struct drive_state[N_DRIVE];
 static struct floppy_write_errors write_errors[N_DRIVE];
 static struct timer_list motor_off_timer[N_DRIVE];
-static struct gendisk *disks[N_DRIVE];
 static struct blk_mq_tag_set tag_sets[N_DRIVE];
 static struct block_device *opened_bdev[N_DRIVE];
 static DEFINE_MUTEX(open_lock);
@@ -477,6 +476,8 @@ static struct floppy_struct floppy_type[32] = {
{ 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5"*/
 };
 
+static struct gendisk *disks[N_DRIVE][ARRAY_SIZE(floppy_type)];
+
 #define SECTSIZE (_FD_SECTSIZE(*floppy))
 
 /* Auto-detection: Disk type used until the next media change occurs. */
@@ -4109,7 +4110,7 @@ static int floppy_open(struct block_device *bdev, fmode_t 
mode)
 
new_dev = MINOR(bdev->bd_dev);
drive_state[drive].fd_device = new_dev;
-   set_capacity(disks[drive], floppy_sizes[new_dev]);
+   set_capacity(disks[drive][ITYPE(new_dev)], floppy_sizes[new_dev]);
if (old_dev != -1 && old_dev != new_dev) {
if (buffer_drive == drive)
buffer_track = -1;
@@ -4577,15 +4578,58 @@ static bool floppy_available(int drive)
return true;
 }
 
-static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+static int floppy_alloc_disk(unsigned int drive, unsigned int type)
 {
-   int drive = (*part & 3) | ((*part & 0x80) >> 5);
-   if (drive >= N_DRIVE || !floppy_available(drive))
-   return NULL;
-   if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
-   return NULL;
-   *part = 0;
-   return get_disk_and_module(disks[drive]);
+   struct gendisk *disk;
+   int err;
+
+   disk = alloc_disk(1);
+   if (!disk)
+   return -ENOMEM;
+
+   disk->queue = blk_mq_init_queue(&tag_sets[drive]);
+   if (IS_ERR(disk->queue)) {
+   err = PTR_ERR(disk->queue);
+   disk->queue = NULL;
+   put_disk(disk);
+   return err;
+   }
+
+   blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
+   blk_queue_max_hw_sectors(disk->queue, 64);
+   disk->major = FLOPPY_MAJOR;
+   disk->first_minor = TOMINOR(drive) | (type << 2);
+   disk->fops = &floppy_fops;
+   disk->events = DISK_EVENT_MEDIA_CHANGE;
+   if (type)
+   sprintf(disk->disk_name, "fd%d_type%d", drive, type);
+   else
+   sprintf(disk->disk_name, "fd%d", drive);
+   /* to be cleaned up... */
+   disk->private_data = (void *)(long)drive;
+   disk->flags |= GENHD_FL_REMOVABLE;
+
+   disks[drive][type] = disk;
+   return 0;
+}
+
+static DEFINE_MUTEX(floppy_probe_lock);
+
+static void floppy_probe(dev_t dev)
+{
+   unsigned int drive = (MINOR(dev) & 3) | ((MINOR(dev) & 0x80) >> 5);
+   unsigned int type = (MINOR(dev) >> 2) & 0x1f;
+
+   if (drive >= N_DRIVE || !floppy_available(drive) ||
+   type >= ARRAY_SIZE(floppy_type))
+   return;
+
+   mutex_lock(&floppy_probe_lock);
+   if (!disks[drive][type]) {
+   if (floppy_alloc_disk(drive, type) == 0)
+   add_disk(disks[drive][type]);
+   }
+   mutex_unlock(&floppy_probe_lock);
 }
 
 static int __init do_floppy_init(void)
@@ -4607,33 +4651,25 @@ static int __init do_floppy_init(void)
return -ENOMEM;
 
for (drive = 0; drive < N_DRIVE; drive++) {
-   disks[drive] = alloc_disk(1);
-   if (!disks[drive]) {
-   err = -ENOMEM;
+   memset(&tag_sets[drive], 0, sizeof(tag_sets[drive]));
+   tag_sets[drive].ops = &floppy_mq_ops;
+   tag_sets[drive].nr_hw_queues = 1;
+   tag_sets[drive].nr_maps = 1;
+   tag_sets[drive].queue_depth = 2;
+   tag_sets[drive].numa_node = NUMA_NO_NODE;
+   tag_sets[drive].flags = BLK_M

Re: [PATCH v6 09/20] gpiolib: cdev: support edge detection for uAPI v2

2020-09-03 Thread Bartosz Golaszewski
On Thu, Sep 3, 2020 at 10:09 AM Kent Gibson  wrote:
>
> On Thu, Sep 03, 2020 at 09:55:22AM +0200, Bartosz Golaszewski wrote:
> > On Mon, Aug 31, 2020 at 5:22 AM Kent Gibson  wrote:
> > >
> > > Add support for edge detection to lines requested using
> > > GPIO_V2_GET_LINE_IOCTL.
> > >
> > > The edge_detector implementation is based on the v1 lineevent
> > > implementation.
> > >
>
> [snip]
>
> > > +* close in time as possible to the actual event.
> > > +*/
> > > +   line->timestamp = ktime_get_ns();
> > > +
> > > +   if (lr->num_lines != 1)
> > > +   line->req_seqno = atomic_inc_return(&lr->seqno);
> >
> > Do we never increase req_seqno for a single line?
> >
>
> For a single line we just use line_seqno for both to avoid the
> atomic_inc here and so reduce the time spent in the ISR and any
> SMP sync overheads.
>
> As per the comment in struct linereq:
>  * @seqno: the sequence number for edge events generated on all lines in
>  * this line request.  Note that this is not used when @num_lines is 1, as
>  * the line_seqno is then the same and is cheaper to calculate.
>
> Cheers,
> Kent.

I should have RTFC I guess. :)

Bart


[PATCH 11/19] loop: use __register_blkdev to allocate devices on demand

2020-09-03 Thread Christoph Hellwig
Use the simpler mechanism attached to major_name to allocate a brd device
when a currently unregistered minor is accessed.

Signed-off-by: Christoph Hellwig 
---
 drivers/block/loop.c | 30 --
 1 file changed, 8 insertions(+), 22 deletions(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index cb1191d6e945f2..15b5a0ea7cc4a9 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -2234,24 +2234,18 @@ static int loop_lookup(struct loop_device **l, int i)
return ret;
 }
 
-static struct kobject *loop_probe(dev_t dev, int *part, void *data)
+static void loop_probe(dev_t dev)
 {
+   int idx = MINOR(dev) >> part_shift;
struct loop_device *lo;
-   struct kobject *kobj;
-   int err;
+
+   if (max_loop && idx >= max_loop)
+   return;
 
mutex_lock(&loop_ctl_mutex);
-   err = loop_lookup(&lo, MINOR(dev) >> part_shift);
-   if (err < 0)
-   err = loop_add(&lo, MINOR(dev) >> part_shift);
-   if (err < 0)
-   kobj = NULL;
-   else
-   kobj = get_disk_and_module(lo->lo_disk);
+   if (loop_lookup(&lo, idx) < 0)
+   loop_add(&lo, idx);
mutex_unlock(&loop_ctl_mutex);
-
-   *part = 0;
-   return kobj;
 }
 
 static long loop_control_ioctl(struct file *file, unsigned int cmd,
@@ -2371,14 +2365,11 @@ static int __init loop_init(void)
goto err_out;
 
 
-   if (register_blkdev(LOOP_MAJOR, "loop")) {
+   if (__register_blkdev(LOOP_MAJOR, "loop", loop_probe)) {
err = -EIO;
goto misc_out;
}
 
-   blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
- THIS_MODULE, loop_probe, NULL, NULL);
-
/* pre-create number of devices given by config or max_loop */
mutex_lock(&loop_ctl_mutex);
for (i = 0; i < nr; i++)
@@ -2404,16 +2395,11 @@ static int loop_exit_cb(int id, void *ptr, void *data)
 
 static void __exit loop_exit(void)
 {
-   unsigned long range;
-
-   range = max_loop ? max_loop << part_shift : 1UL << MINORBITS;
-
mutex_lock(&loop_ctl_mutex);
 
idr_for_each(&loop_index_idr, &loop_exit_cb, NULL);
idr_destroy(&loop_index_idr);
 
-   blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range);
unregister_blkdev(LOOP_MAJOR, "loop");
 
misc_deregister(&loop_misc);
-- 
2.28.0



[PATCH 08/19] swim: don't call blk_register_region

2020-09-03 Thread Christoph Hellwig
The swim driver (unlike various other floppy drivers) doesn't have
magic device nodes for certain modes, and already registers a gendisk
for each of the floppies supported by a device.  Thus the region
registered is a no-op and can be removed.

Signed-off-by: Christoph Hellwig 
---
 drivers/block/swim.c | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index dd34504382e533..5a8f5932f9bde4 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -763,18 +763,6 @@ static const struct block_device_operations floppy_fops = {
.revalidate_disk = floppy_revalidate,
 };
 
-static struct kobject *floppy_find(dev_t dev, int *part, void *data)
-{
-   struct swim_priv *swd = data;
-   int drive = (*part & 3);
-
-   if (drive >= swd->floppy_count)
-   return NULL;
-
-   *part = 0;
-   return get_disk_and_module(swd->unit[drive].disk);
-}
-
 static int swim_add_floppy(struct swim_priv *swd, enum drive_location location)
 {
struct floppy_state *fs = &swd->unit[swd->floppy_count];
@@ -864,9 +852,6 @@ static int swim_floppy_init(struct swim_priv *swd)
add_disk(swd->unit[drive].disk);
}
 
-   blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
-   floppy_find, NULL, swd);
-
return 0;
 
 exit_put_disks:
@@ -950,8 +935,6 @@ static int swim_remove(struct platform_device *dev)
int drive;
struct resource *res;
 
-   blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
-
for (drive = 0; drive < swd->floppy_count; drive++) {
del_gendisk(swd->unit[drive].disk);
blk_cleanup_queue(swd->unit[drive].disk->queue);
-- 
2.28.0



Re: [PATCH 2/2] iommu: amd: Use cmpxchg_double() when updating 128-bit IRTE

2020-09-03 Thread Suravee Suthikulpanit

Hi,

I'll send out V2 with fixes to the review comments below ...

On 9/2/20 10:26 PM, Joao Martins wrote:

On 9/2/20 5:51 AM, Suravee Suthikulpanit wrote:

When using 128-bit interrupt-remapping table entry (IRTE) (a.k.a GA mode),
current driver disables interrupt remapping when it updates the IRTE
so that the upper and lower 64-bit values can be updated safely.

However, this creates a small window, where the interrupt could
arrive and result in IO_PAGE_FAULT (for interrupt) as shown below.

   IOMMU DriverDevice IRQ
   ===
   irte.RemapEn=0
...
change IRTEIRQ from device ==> IO_PAGE_FAULT !!
...
   irte.RemapEn=1

This scenario has been observed when changing irq affinity on a system
running I/O-intensive workload, in which the destination APIC ID
in the IRTE is updated.

Instead, use cmpxchg_double() to update the 128-bit IRTE at once without
disabling the interrupt remapping. However, this means several features,
which require GA (128-bit IRTE) support will also be affected if cmpxchg16b
is not supported (which is unprecedented for AMD processors w/ IOMMU).


Probably requires:

  Fixes: 880ac60e2538 ("iommu/amd: Introduce interrupt remapping ops structure")



Yes, I will include this in V2.




Reported-by: Sean Osborne 
Tested-by: Erik Rockstrom 
Signed-off-by: Suravee Suthikulpanit 


With the comments below addressed, FWIW:

  Reviewed-by: Joao Martins 


diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index c652f16eb702..ad30467f6930 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -1511,7 +1511,14 @@ static int __init init_iommu_one(struct amd_iommu 
*iommu, struct ivhd_header *h)
iommu->mmio_phys_end = MMIO_REG_END_OFFSET;
else
iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
-   if (((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0))
+
+   /*
+* Note: GA (128-bit IRTE) mode requires cmpxchg16b supports.
+* GAM also requires GA mode. Therefore, we need to
+* check cmbxchg16b support before enabling it.
+*/


s/cmbxchg16b/cmpxchg16b


+   if (!boot_cpu_has(X86_FEATURE_CX16) ||
+   ((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0))
amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
break;
case 0x11:
@@ -1520,8 +1527,18 @@ static int __init init_iommu_one(struct amd_iommu 
*iommu, struct ivhd_header *h)
iommu->mmio_phys_end = MMIO_REG_END_OFFSET;
else
iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
-   if (((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0))
+
+   /*
+* Note: GA (128-bit IRTE) mode requires cmpxchg16b supports.
+* XT, GAM also requires GA mode. Therefore, we need to
+* check cmbxchg16b support before enabling them.


s/cmbxchg16b/cmpxchg16b


+*/
+   if (boot_cpu_has(X86_FEATURE_CX16) ||


You probably want !boot_cpu_has(X86_FEATURE_CX16) ?


 Ah, sorry!! I forgot to change it back after testing for the negative 
case. Thank you for catching this.

Suravee




+   ((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0)) {
amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
+   break;
+   }
+
/*
 * Note: Since iommu_update_intcapxt() leverages
 * the IOMMU MMIO access to MSI capability block registers


Re: [PATCH 16/19] ataflop: use a separate gendisk for each media format

2020-09-03 Thread John Paul Adrian Glaubitz
Hi Christoph!

On 9/3/20 10:01 AM, Christoph Hellwig wrote:
> The Atari floppy driver usually autodetects the media when used with the
> ormal /dev/fd? devices, which also are the only nodes created by udev.
  
  typo?

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaub...@debian.org
`. `'   Freie Universitaet Berlin - glaub...@physik.fu-berlin.de
  `-GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


simplify gendisk lookup and remove struct block_device aliases v3

2020-09-03 Thread Christoph Hellwig
Hi all,

this series removes the annoying struct block_device aliases, which can
happen for a bunch of old floppy drivers (and z2ram).  In that case
multiple struct block device instances for different dev_t's can point
to the same gendisk, without being partitions.  The cause for that
is the probe/get callback registered through blk_register_regions.

This series removes blk_register_region entirely, splitting it it into
a simple xarray lookup of registered gendisks, and a probe callback
stored in the major_names array that can be used for modprobe overrides
or creating devices on demands when no gendisk is found.  The old
remapping is gone entirely, and instead the 4 remaining drivers just
register a gendisk for each operating mode.  In case of the two drivers
that have lots of aliases that is done on-demand using the new probe
callback, while for the other two I simply register all at probe time
to keep things simple.

Note that the m68k drivers are compile tested only.

Changes since v2:
 - fix a wrong variable passed to ERR_PTR in the floppy driver
 - slightly adjust the del_gendisk cleanups to prepare for the next
   series touching this area

Changes since v1:
 - add back a missing kobject_put in the cdev code
 - improve the xarray delete loops

Diffstat:
 b/block/genhd.c   |  183 +++
 b/drivers/base/Makefile   |2 
 b/drivers/block/amiflop.c |   98 
 b/drivers/block/ataflop.c |  135 +++
 b/drivers/block/brd.c |   39 ---
 b/drivers/block/floppy.c  |  154 
 b/drivers/block/loop.c|   30 --
 b/drivers/block/swim.c|   17 -
 b/drivers/block/z2ram.c   |  547 ++
 b/drivers/ide/ide-probe.c |   66 -
 b/drivers/ide/ide-tape.c  |2 
 b/drivers/md/md.c |   21 -
 b/drivers/scsi/sd.c   |   19 -
 b/fs/char_dev.c   |   94 +++
 b/fs/dcache.c |1 
 b/fs/internal.h   |5 
 b/include/linux/genhd.h   |   12 -
 b/include/linux/ide.h |3 
 drivers/base/map.c|  154 
 include/linux/kobj_map.h  |   20 -
 20 files changed, 686 insertions(+), 916 deletions(-)


[PATCH 09/19] sd: use __register_blkdev to avoid a modprobe for an unregistered dev_t

2020-09-03 Thread Christoph Hellwig
Switch from using blk_register_region to the probe callback passed to
__register_blkdev to disable the request_module call for an unclaimed
dev_t in the SD majors.

Signed-off-by: Christoph Hellwig 
---
 drivers/scsi/sd.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 2bec8cd526164d..97bf84b1871571 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -596,13 +596,11 @@ static struct scsi_driver sd_template = {
 };
 
 /*
- * Dummy kobj_map->probe function.
- * The default ->probe function will call modprobe, which is
- * pointless as this module is already loaded.
+ * Don't request a new module, as that could deadlock in multipath
+ * environment.
  */
-static struct kobject *sd_default_probe(dev_t devt, int *partno, void *data)
+static void sd_default_probe(dev_t devt)
 {
-   return NULL;
 }
 
 /*
@@ -3481,9 +3479,6 @@ static int sd_remove(struct device *dev)
 
free_opal_dev(sdkp->opal_dev);
 
-   blk_register_region(devt, SD_MINORS, NULL,
-   sd_default_probe, NULL, NULL);
-
mutex_lock(&sd_ref_mutex);
dev_set_drvdata(dev, NULL);
put_device(&sdkp->dev);
@@ -3673,11 +3668,9 @@ static int __init init_sd(void)
SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
 
for (i = 0; i < SD_MAJORS; i++) {
-   if (register_blkdev(sd_major(i), "sd") != 0)
+   if (__register_blkdev(sd_major(i), "sd", sd_default_probe))
continue;
majors++;
-   blk_register_region(sd_major(i), SD_MINORS, NULL,
-   sd_default_probe, NULL, NULL);
}
 
if (!majors)
@@ -3750,10 +3743,8 @@ static void __exit exit_sd(void)
 
class_unregister(&sd_disk_class);
 
-   for (i = 0; i < SD_MAJORS; i++) {
-   blk_unregister_region(sd_major(i), SD_MINORS);
+   for (i = 0; i < SD_MAJORS; i++)
unregister_blkdev(sd_major(i), "sd");
-   }
 }
 
 module_init(init_sd);
-- 
2.28.0



[PATCH 07/19] ide: remove ide_{,un}register_region

2020-09-03 Thread Christoph Hellwig
There is no need to ever register the fake gendisk used for ide-tape.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Hannes Reinecke 
---
 drivers/ide/ide-probe.c | 32 
 drivers/ide/ide-tape.c  |  2 --
 include/linux/ide.h |  3 ---
 3 files changed, 37 deletions(-)

diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 1ddc45a04418cd..076d34b381720f 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -929,38 +929,6 @@ static struct kobject *ata_probe(dev_t dev, int *part, 
void *data)
return NULL;
 }
 
-static struct kobject *exact_match(dev_t dev, int *part, void *data)
-{
-   struct gendisk *p = data;
-   *part &= (1 << PARTN_BITS) - 1;
-   return &disk_to_dev(p)->kobj;
-}
-
-static int exact_lock(dev_t dev, void *data)
-{
-   struct gendisk *p = data;
-
-   if (!get_disk_and_module(p))
-   return -1;
-   return 0;
-}
-
-void ide_register_region(struct gendisk *disk)
-{
-   blk_register_region(MKDEV(disk->major, disk->first_minor),
-   disk->minors, NULL, exact_match, exact_lock, disk);
-}
-
-EXPORT_SYMBOL_GPL(ide_register_region);
-
-void ide_unregister_region(struct gendisk *disk)
-{
-   blk_unregister_region(MKDEV(disk->major, disk->first_minor),
- disk->minors);
-}
-
-EXPORT_SYMBOL_GPL(ide_unregister_region);
-
 void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
 {
ide_hwif_t *hwif = drive->hwif;
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 6f26634b22bbec..88b96437b22e62 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1822,7 +1822,6 @@ static void ide_tape_remove(ide_drive_t *drive)
 
ide_proc_unregister_driver(drive, tape->driver);
device_del(&tape->dev);
-   ide_unregister_region(tape->disk);
 
mutex_lock(&idetape_ref_mutex);
put_device(&tape->dev);
@@ -2026,7 +2025,6 @@ static int ide_tape_probe(ide_drive_t *drive)
  "n%s", tape->name);
 
g->fops = &idetape_block_ops;
-   ide_register_region(g);
 
return 0;
 
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a254841bd3156d..cfa9e4b0c325a4 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1495,9 +1495,6 @@ static inline void ide_acpi_port_init_devices(ide_hwif_t 
*hwif) { ; }
 static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {}
 #endif
 
-void ide_register_region(struct gendisk *);
-void ide_unregister_region(struct gendisk *);
-
 void ide_check_nien_quirk_list(ide_drive_t *);
 void ide_undecoded_slave(ide_drive_t *);
 
-- 
2.28.0



[PATCH v8 5/6] media: i2c: imx319: Support probe while the device is off

2020-09-03 Thread Sakari Ailus
From: Rajmohan Mani 

Tell ACPI device PM code that the driver supports the device being powered
off when the driver's probe function is entered.

Signed-off-by: Rajmohan Mani 
Signed-off-by: Sakari Ailus 
---
 drivers/media/i2c/imx319.c | 74 +++---
 1 file changed, 45 insertions(+), 29 deletions(-)

diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c
index 17c2e4b41221e..6b63bb0abb138 100644
--- a/drivers/media/i2c/imx319.c
+++ b/drivers/media/i2c/imx319.c
@@ -140,6 +140,8 @@ struct imx319 {
 
/* Streaming on/off */
bool streaming;
+   /* True if the device has been identified */
+   bool identified;
 };
 
 static const struct imx319_reg imx319_global_regs[] = {
@@ -2084,6 +2086,31 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
return 0;
 }
 
+/* Verify chip ID */
+static int imx319_identify_module(struct imx319 *imx319)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
+   int ret;
+   u32 val;
+
+   if (imx319->identified)
+   return 0;
+
+   ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
+   if (ret)
+   return ret;
+
+   if (val != IMX319_CHIP_ID) {
+   dev_err(&client->dev, "chip id mismatch: %x!=%x",
+   IMX319_CHIP_ID, val);
+   return -EIO;
+   }
+
+   imx319->identified = true;
+
+   return 0;
+}
+
 /* Start streaming */
 static int imx319_start_streaming(struct imx319 *imx319)
 {
@@ -2091,6 +2118,10 @@ static int imx319_start_streaming(struct imx319 *imx319)
const struct imx319_reg_list *reg_list;
int ret;
 
+   ret = imx319_identify_module(imx319);
+   if (ret)
+   return ret;
+
/* Global Setting */
reg_list = &imx319_global_setting;
ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
@@ -2210,26 +2241,6 @@ static int __maybe_unused imx319_resume(struct device 
*dev)
return ret;
 }
 
-/* Verify chip ID */
-static int imx319_identify_module(struct imx319 *imx319)
-{
-   struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
-   int ret;
-   u32 val;
-
-   ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
-   if (ret)
-   return ret;
-
-   if (val != IMX319_CHIP_ID) {
-   dev_err(&client->dev, "chip id mismatch: %x!=%x",
-   IMX319_CHIP_ID, val);
-   return -EIO;
-   }
-
-   return 0;
-}
-
 static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = {
.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
@@ -2424,6 +2435,7 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct 
device *dev)
 static int imx319_probe(struct i2c_client *client)
 {
struct imx319 *imx319;
+   bool low_power;
int ret;
u32 i;
 
@@ -2436,11 +2448,14 @@ static int imx319_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
 
-   /* Check module identity */
-   ret = imx319_identify_module(imx319);
-   if (ret) {
-   dev_err(&client->dev, "failed to find sensor: %d", ret);
-   goto error_probe;
+   low_power = acpi_dev_state_low_power(&client->dev);
+   if (!low_power) {
+   /* Check module identity */
+   ret = imx319_identify_module(imx319);
+   if (ret) {
+   dev_err(&client->dev, "failed to find sensor: %d", ret);
+   goto error_probe;
+   }
}
 
imx319->hwcfg = imx319_get_hwcfg(&client->dev);
@@ -2493,10 +2508,10 @@ static int imx319_probe(struct i2c_client *client)
goto error_media_entity;
 
/*
-* Device is already turned on by i2c-core with ACPI domain PM.
-* Enable runtime PM and turn off the device.
+* Don't set the device's state to active if it's in a low power state.
 */
-   pm_runtime_set_active(&client->dev);
+   if (!low_power)
+   pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
 
@@ -2536,7 +2551,7 @@ static const struct dev_pm_ops imx319_pm_ops = {
 };
 
 static const struct acpi_device_id imx319_acpi_ids[] = {
-   { "SONY319A" },
+   { "SONY319A", },
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(acpi, imx319_acpi_ids);
@@ -2549,6 +2564,7 @@ static struct i2c_driver imx319_i2c_driver = {
},
.probe_new = imx319_probe,
.remove = imx319_remove,
+   .flags = I2C_DRV_FL_ALLOW_LOW_POWER_PROBE,
 };
 module_i2c_driver(imx319_i2c_driver);
 
-- 
2.20.1



linux-next: Tree for Sep 3

2020-09-03 Thread Stephen Rothwell
Hi all,

News: There will be no linux-next release tomorrow or Monday.

Changes since 20200902:

The tip tree merged badly today so I had to apply a merge fix patch.

The scsi-mkp tree gained a conflict against Linus' tree.

Non-merge commits (relative to Linus' tree): 4011
 5122 files changed, 145893 insertions(+), 64144 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc, an allmodconfig for x86_64, a
multi_v7_defconfig for arm and a native build of tools/perf. After
the final fixups (if any), I do an x86_64 modules_install followed by
builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit),
ppc44x_defconfig, allyesconfig and pseries_le_defconfig and i386, sparc
and sparc64 defconfig and htmldocs. And finally, a simple boot test
of the powerpc pseries_le_defconfig kernel in qemu (with and without
kvm enabled).

Below is a summary of the state of the merge.

I am currently merging 328 trees (counting Linus' and 86 trees of bug
fix patches pending for the current merge release).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (fc3abb53250a Merge branch 'for-linus' of 
git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid)
Merging fixes/fixes (9123e3a74ec7 Linux 5.9-rc1)
Merging kbuild-current/fixes (844cbb93dd92 kconfig: remove redundant assignment 
prompt = prompt)
Merging arc-current/for-curr (26907eb605fb ARC: [plat-hsdk]: Switch ethernet 
phy-mode to rgmii-id)
Merging arm-current/fixes (5c6360ee4a0e ARM: 8988/1: mmu: fix crash in EFI 
calls due to p4d typo in create_mapping_late())
Merging arm64-fixes/for-next/fixes (e0328feda79d arm64/module: set trampoline 
section flags regardless of CONFIG_DYNAMIC_FTRACE)
Merging arm-soc-fixes/arm/fixes (9c8b0a9c37b7 Merge tag 'imx-fixes-5.9' of 
git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/fixes)
Merging uniphier-fixes/fixes (48778464bb7d Linux 5.8-rc2)
Merging drivers-memory-fixes/fixes (7ff3a2a626f7 memory: jz4780_nemc: Fix an 
error pointer vs NULL check in probe())
Merging m68k-current/for-linus (382f429bb559 m68k: defconfig: Update defconfigs 
for v5.8-rc3)
Merging powerpc-fixes/fixes (fc1f178cdb31 selftests/powerpc: Skip PROT_SAO test 
in guests/LPARS)
Merging s390-fixes/fixes (5c60ed283e1d s390: update defconfigs)
Merging sparc/master (0a95a6d1a4cd sparc: use for_each_child_of_node() macro)
Merging fscrypt-current/for-stable (2b4eae95c736 fscrypt: don't evict dirty 
inodes after removing key)
Merging net/master (1996cf46e467 net: bcmgenet: fix mask check in 
bcmgenet_validate_flow())
Merging bpf/master (1eb832ac2dee tools/bpf: build: Make sure resolve_btfids 
cleans up after itself)
Merging ipsec/master (45a36a18d019 xfrmi: drop ignore_df check before updating 
pmtu)
Merging netfilter/master (6b6382a857d8 cxgb4: fix thermal zone device 
registration)
Merging ipvs/master (7c7ab580db49 net: Convert to use the fallthrough macro)
Merging wireless-drivers/master (4afc850e2e9e mwifiex: Increase AES key storage 
size to 256 bits)
Merging mac80211/master (c8146fe292a7 Merge 
git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf)
Merging rdma-fixes/for-rc (097a9d23b725 RDMA/bnxt_re: Remove the qp from list 
only if the qp destroy succeeds)
Merging sound-current/for-linus (b79de57b4378 ALSA: hda: use consistent HDAudio 
spelling in comments/docs)
Merging sound-asoc-fixes/for-linus (7a1852b61773 Merge remote-tracking branch 
'asoc/for-5.9' into asoc-linus)
Merging regmap-fixes/for-linus (f75aef392f86 Linux 5.9-rc3)
Merging regulator-fixes/for-linus (4d59222e60d3 Merge remote-tracking branch 
'regulator/for-5.9' into regulator-linus)
Merging spi-fixes/for-linus (3ffc1e24ed59 Merge remote-tracking branch 
'spi/for-5.9' into spi-linus)
Merging pci-current/for-linus (7c2308f79fc8 PCI/P2PDMA: Fix build without DMA 
ops)
Merging driver-core.current/driver-core-linus (40b8b826a699 kobject: Restore 
old behaviour of k

[PATCH v8 1/6] i2c: Allow an ACPI driver to manage the device's power state during probe

2020-09-03 Thread Sakari Ailus
Enable drivers to tell ACPI that there's no need to power on a device for
probe. Drivers should still perform this by themselves if there's a need
to. In some cases powering on the device during probe is undesirable, and
this change enables a driver to choose what fits best for it.

Add a field called "flags" into struct i2c_driver for driver flags, and a
flag I2C_DRV_FL_ALLOW_LOW_POWER_PROBE to tell a driver supports probe in
low power state.

Signed-off-by: Sakari Ailus 
---
 drivers/i2c/i2c-core-base.c | 19 ---
 include/linux/i2c.h | 14 ++
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 5ec082e2039d9..cfb1e777c6196 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -436,6 +436,16 @@ static int i2c_smbus_host_notify_to_irq(const struct 
i2c_client *client)
return irq > 0 ? irq : -ENXIO;
 }
 
+static bool allow_low_power_probe(struct device *dev)
+{
+   struct i2c_driver *driver = to_i2c_driver(dev->driver);
+
+   return driver->flags & I2C_DRV_FL_ALLOW_LOW_POWER_PROBE &&
+   !acpi_dev_get_property(ACPI_COMPANION(dev),
+  "i2c-allow-low-power-probe",
+  ACPI_TYPE_ANY, NULL);
+}
+
 static int i2c_device_probe(struct device *dev)
 {
struct i2c_client   *client = i2c_verify_client(dev);
@@ -514,7 +524,8 @@ static int i2c_device_probe(struct device *dev)
if (status < 0)
goto err_clear_wakeup_irq;
 
-   status = dev_pm_domain_attach(&client->dev, true);
+   status = dev_pm_domain_attach(&client->dev,
+ !allow_low_power_probe(&client->dev));
if (status)
goto err_clear_wakeup_irq;
 
@@ -536,7 +547,8 @@ static int i2c_device_probe(struct device *dev)
return 0;
 
 err_detach_pm_domain:
-   dev_pm_domain_detach(&client->dev, true);
+   dev_pm_domain_detach(&client->dev,
+!allow_low_power_probe(&client->dev));
 err_clear_wakeup_irq:
dev_pm_clear_wake_irq(&client->dev);
device_init_wakeup(&client->dev, false);
@@ -562,7 +574,8 @@ static int i2c_device_remove(struct device *dev)
status = driver->remove(client);
}
 
-   dev_pm_domain_detach(&client->dev, true);
+   dev_pm_domain_detach(&client->dev,
+!allow_low_power_probe(&client->dev));
 
dev_pm_clear_wake_irq(&client->dev);
device_init_wakeup(&client->dev, false);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index fc55ea41d3237..f8c3257a8bb25 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -11,6 +11,7 @@
 #define _LINUX_I2C_H
 
 #include /* for acpi_handle */
+#include 
 #include 
 #include   /* for struct device */
 #include/* for completion */
@@ -217,6 +218,16 @@ enum i2c_alert_protocol {
I2C_PROTOCOL_SMBUS_HOST_NOTIFY,
 };
 
+/**
+ * enum i2c_driver_flags - Flags for an I2C device driver
+ *
+ * @I2C_DRV_FL_ALLOW_LOW_POWER_PROBE: Let the ACPI driver manage the device's
+ *   power state during probe and remove
+ */
+enum i2c_driver_flags {
+   I2C_DRV_FL_ALLOW_LOW_POWER_PROBE = BIT(0),
+};
+
 /**
  * struct i2c_driver - represent an I2C device driver
  * @class: What kind of i2c device we instantiate (for detect)
@@ -231,6 +242,7 @@ enum i2c_alert_protocol {
  * @detect: Callback for device detection
  * @address_list: The I2C addresses to probe (for detect)
  * @clients: List of detected clients we created (for i2c-core use only)
+ * @flags: A bitmask of flags defined in &enum i2c_driver_flags
  *
  * The driver.owner field should be set to the module owner of this driver.
  * The driver.name field should be set to the name of this driver.
@@ -289,6 +301,8 @@ struct i2c_driver {
int (*detect)(struct i2c_client *client, struct i2c_board_info *info);
const unsigned short *address_list;
struct list_head clients;
+
+   u32 flags;
 };
 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
 
-- 
2.20.1



[PATCH v8 6/6] at24: Support probing while off

2020-09-03 Thread Sakari Ailus
In certain use cases (where the chip is part of a camera module, and the
camera module is wired together with a camera privacy LED), powering on
the device during probe is undesirable. Add support for the at24 to
execute probe while being powered off. For this to happen, a hint in form
of a device property is required from the firmware.

Signed-off-by: Sakari Ailus 
---
 drivers/misc/eeprom/at24.c | 43 +++---
 1 file changed, 26 insertions(+), 17 deletions(-)

diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 8f5de5f10bbea..2d24e33788d7d 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -595,6 +595,7 @@ static int at24_probe(struct i2c_client *client)
bool i2c_fn_i2c, i2c_fn_block;
unsigned int i, num_addresses;
struct at24_data *at24;
+   bool low_power;
struct regmap *regmap;
bool writable;
u8 test_byte;
@@ -733,25 +734,30 @@ static int at24_probe(struct i2c_client *client)
 
i2c_set_clientdata(client, at24);
 
-   err = regulator_enable(at24->vcc_reg);
-   if (err) {
-   dev_err(dev, "Failed to enable vcc regulator\n");
-   return err;
-   }
+   low_power = acpi_dev_state_low_power(&client->dev);
+   if (!low_power) {
+   err = regulator_enable(at24->vcc_reg);
+   if (err) {
+   dev_err(dev, "Failed to enable vcc regulator\n");
+   return err;
+   }
 
-   /* enable runtime pm */
-   pm_runtime_set_active(dev);
+   pm_runtime_set_active(dev);
+   }
pm_runtime_enable(dev);
 
/*
-* Perform a one-byte test read to verify that the
-* chip is functional.
+* Perform a one-byte test read to verify that the chip is functional,
+* unless powering on the device is to be avoided during probe (i.e.
+* it's powered off right now).
 */
-   err = at24_read(at24, 0, &test_byte, 1);
-   if (err) {
-   pm_runtime_disable(dev);
-   regulator_disable(at24->vcc_reg);
-   return -ENODEV;
+   if (!low_power) {
+   err = at24_read(at24, 0, &test_byte, 1);
+   if (err) {
+   pm_runtime_disable(dev);
+   regulator_disable(at24->vcc_reg);
+   return -ENODEV;
+   }
}
 
pm_runtime_idle(dev);
@@ -771,9 +777,11 @@ static int at24_remove(struct i2c_client *client)
struct at24_data *at24 = i2c_get_clientdata(client);
 
pm_runtime_disable(&client->dev);
-   if (!pm_runtime_status_suspended(&client->dev))
-   regulator_disable(at24->vcc_reg);
-   pm_runtime_set_suspended(&client->dev);
+   if (!acpi_dev_state_low_power(&client->dev)) {
+   if (!pm_runtime_status_suspended(&client->dev))
+   regulator_disable(at24->vcc_reg);
+   pm_runtime_set_suspended(&client->dev);
+   }
 
return 0;
 }
@@ -810,6 +818,7 @@ static struct i2c_driver at24_driver = {
.probe_new = at24_probe,
.remove = at24_remove,
.id_table = at24_ids,
+   .flags = I2C_DRV_FL_ALLOW_LOW_POWER_PROBE,
 };
 
 static int __init at24_init(void)
-- 
2.20.1



[PATCH v8 4/6] ov5670: Support probe whilst the device is in a low power state

2020-09-03 Thread Sakari Ailus
Tell ACPI device PM code that the driver supports the device being in a
low power state when the driver's probe function is entered.

Also do identification on the first access of the device, whether in probe
or when starting streaming.

Signed-off-by: Sakari Ailus 
---
 drivers/media/i2c/ov5670.c | 76 +++---
 1 file changed, 46 insertions(+), 30 deletions(-)

diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index f26252e35e08d..74b0325c22565 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -1832,6 +1832,8 @@ struct ov5670 {
 
/* Streaming on/off */
bool streaming;
+   /* True if the device has been identified */
+   bool identified;
 };
 
 #define to_ov5670(_sd) container_of(_sd, struct ov5670, sd)
@@ -2270,6 +2272,32 @@ static int ov5670_get_skip_frames(struct v4l2_subdev 
*sd, u32 *frames)
return 0;
 }
 
+/* Verify chip ID */
+static int ov5670_identify_module(struct ov5670 *ov5670)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
+   int ret;
+   u32 val;
+
+   if (ov5670->identified)
+   return 0;
+
+   ret = ov5670_read_reg(ov5670, OV5670_REG_CHIP_ID,
+ OV5670_REG_VALUE_24BIT, &val);
+   if (ret)
+   return ret;
+
+   if (val != OV5670_CHIP_ID) {
+   dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+   OV5670_CHIP_ID, val);
+   return -ENXIO;
+   }
+
+   ov5670->identified = true;
+
+   return 0;
+}
+
 /* Prepare streaming by writing default values and customized values */
 static int ov5670_start_streaming(struct ov5670 *ov5670)
 {
@@ -2278,6 +2306,10 @@ static int ov5670_start_streaming(struct ov5670 *ov5670)
int link_freq_index;
int ret;
 
+   ret = ov5670_identify_module(ov5670);
+   if (ret)
+   return ret;
+
/* Get out of from software reset */
ret = ov5670_write_reg(ov5670, OV5670_REG_SOFTWARE_RST,
   OV5670_REG_VALUE_08BIT, OV5670_SOFTWARE_RST);
@@ -2401,27 +2433,6 @@ static int __maybe_unused ov5670_resume(struct device 
*dev)
return 0;
 }
 
-/* Verify chip ID */
-static int ov5670_identify_module(struct ov5670 *ov5670)
-{
-   struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
-   int ret;
-   u32 val;
-
-   ret = ov5670_read_reg(ov5670, OV5670_REG_CHIP_ID,
- OV5670_REG_VALUE_24BIT, &val);
-   if (ret)
-   return ret;
-
-   if (val != OV5670_CHIP_ID) {
-   dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
-   OV5670_CHIP_ID, val);
-   return -ENXIO;
-   }
-
-   return 0;
-}
-
 static const struct v4l2_subdev_video_ops ov5670_video_ops = {
.s_stream = ov5670_set_stream,
 };
@@ -2456,6 +2467,7 @@ static int ov5670_probe(struct i2c_client *client)
struct ov5670 *ov5670;
const char *err_msg;
u32 input_clk = 0;
+   bool low_power;
int ret;
 
device_property_read_u32(&client->dev, "clock-frequency", &input_clk);
@@ -2472,11 +2484,14 @@ static int ov5670_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops);
 
-   /* Check module identity */
-   ret = ov5670_identify_module(ov5670);
-   if (ret) {
-   err_msg = "ov5670_identify_module() error";
-   goto error_print;
+   low_power = acpi_dev_state_low_power(&client->dev);
+   if (!low_power) {
+   /* Check module identity */
+   ret = ov5670_identify_module(ov5670);
+   if (ret) {
+   err_msg = "ov5670_identify_module() error";
+   goto error_print;
+   }
}
 
mutex_init(&ov5670->mutex);
@@ -2513,10 +2528,10 @@ static int ov5670_probe(struct i2c_client *client)
ov5670->streaming = false;
 
/*
-* Device is already turned on by i2c-core with ACPI domain PM.
-* Enable runtime PM and turn off the device.
+* Don't set the device's state to active if it's in a low power state.
 */
-   pm_runtime_set_active(&client->dev);
+   if (!low_power)
+   pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
 
@@ -2558,7 +2573,7 @@ static const struct dev_pm_ops ov5670_pm_ops = {
 
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id ov5670_acpi_ids[] = {
-   {"INT3479"},
+   { "INT3479" },
{ /* sentinel */ }
 };
 
@@ -2573,6 +2588,7 @@ static struct i2c_driver ov5670_i2c_driver = {
},
.probe_new = ov5670_probe,
.remove = ov5670_remove,
+   .flags = I2C_DRV_FL_ALLOW_LOW_POWER_PROBE,
 };
 
 module_i2c_driver(ov5670_i2c_driver);
-- 
2.20.1


[PATCH v8 2/6] Documentation: ACPI: Document i2c-allow-low-power-probe _DSD property

2020-09-03 Thread Sakari Ailus
Document the probe-low-power _DSD property and how it is used with I²C
drivers.

Signed-off-by: Sakari Ailus 
---
 .../acpi/dsd/i2c-allow-low-power-probe.rst| 60 +++
 Documentation/firmware-guide/acpi/index.rst   |  1 +
 2 files changed, 61 insertions(+)
 create mode 100644 
Documentation/firmware-guide/acpi/dsd/i2c-allow-low-power-probe.rst

diff --git 
a/Documentation/firmware-guide/acpi/dsd/i2c-allow-low-power-probe.rst 
b/Documentation/firmware-guide/acpi/dsd/i2c-allow-low-power-probe.rst
new file mode 100644
index 0..7e7ed3ad3ac69
--- /dev/null
+++ b/Documentation/firmware-guide/acpi/dsd/i2c-allow-low-power-probe.rst
@@ -0,0 +1,60 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==
+Probing I²C devices in low power state
+==
+
+Introduction
+
+
+In some cases it may be preferred to leave certain devices powered off for the
+entire system bootup if powering on these devices has adverse side effects,
+beyond just powering on the said device. Linux recognizes the _DSD property [1]
+"i2c-allow-low-power-probe" that can be used for this purpose.
+
+How it works
+
+
+The boolean device property "i2c-allow-low-power-probe" may be used to tell
+Linux that the I²C framework should instruct the kernel ACPI framework to leave
+the device in the low power state. If the driver indicates its support for this
+by setting the I2C_DRV_FL_ALLOW_LOW_POWER_PROBE flag in struct i2c_driver.flags
+field and the "i2c-allow-low-power-probe" property is present, the device will
+not be powered on for probe.
+
+The downside is that as the device is not powered on, even if there's a problem
+with the device, the driver likely probes just fine but the first user will
+find out the device doesn't work, instead of a failure at probe time. This
+feature should thus be used sparingly.
+
+Example
+===
+
+An ASL example describing an ACPI device using this property looks like
+this. Some objects not relevant from the example point of view have been
+omitted.
+
+   Device (CAM0)
+{
+   Name (_HID, "SONY319A")
+   Name (_UID, Zero)
+   Name (_CRS, ResourceTemplate ()
+   {
+   I2cSerialBus(0x0020, ControllerInitiated, 0x00061A80,
+AddressingMode7Bit, "\\_SB.PCI0.I2C0",
+0x00, ResourceConsumer)
+   })
+   Name (PRT4, Package() {
+   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+   Package () {
+   Package () { "i2c-allow-low-power-probe", 1 },
+   }
+})
+   }
+
+References
+==
+
+[1] Device Properties UUID For _DSD.
+
https://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf,
+referenced 2020-09-02.
diff --git a/Documentation/firmware-guide/acpi/index.rst 
b/Documentation/firmware-guide/acpi/index.rst
index ad3b5afdae77e..1f87b7072d1e6 100644
--- a/Documentation/firmware-guide/acpi/index.rst
+++ b/Documentation/firmware-guide/acpi/index.rst
@@ -11,6 +11,7 @@ ACPI Support
dsd/graph
dsd/data-node-references
dsd/leds
+   dsd/i2c-allow-low-power-probe
enumeration
osi
method-customizing
-- 
2.20.1



[PATCH 06/19] block: add an optional probe callback to major_names

2020-09-03 Thread Christoph Hellwig
Add a callback to the major_names array that allows a driver to override
how to probe for dev_t that doesn't currently have a gendisk registered.
This will help separating the lookup of the gendisk by dev_t vs probe
action for a not currently registered dev_t.

Signed-off-by: Christoph Hellwig 
---
 block/genhd.c | 21 ++---
 include/linux/genhd.h |  5 -
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index d9ecc751fc956c..3abd764443a6af 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -399,6 +399,7 @@ static struct blk_major_name {
struct blk_major_name *next;
int major;
char name[16];
+   void (*probe)(dev_t devt);
 } *major_names[BLKDEV_MAJOR_HASH_SIZE];
 static DEFINE_MUTEX(major_names_lock);
 
@@ -441,7 +442,8 @@ void blkdev_show(struct seq_file *seqf, off_t offset)
  * See Documentation/admin-guide/devices.txt for the list of allocated
  * major numbers.
  */
-int register_blkdev(unsigned int major, const char *name)
+int __register_blkdev(unsigned int major, const char *name,
+   void (*probe)(dev_t devt))
 {
struct blk_major_name **n, *p;
int index, ret = 0;
@@ -480,6 +482,7 @@ int register_blkdev(unsigned int major, const char *name)
}
 
p->major = major;
+   p->probe = probe;
strlcpy(p->name, name, sizeof(p->name));
p->next = NULL;
index = major_to_index(major);
@@ -502,8 +505,7 @@ int register_blkdev(unsigned int major, const char *name)
mutex_unlock(&major_names_lock);
return ret;
 }
-
-EXPORT_SYMBOL(register_blkdev);
+EXPORT_SYMBOL(__register_blkdev);
 
 void unregister_blkdev(unsigned int major, const char *name)
 {
@@ -1035,6 +1037,19 @@ static ssize_t disk_badblocks_store(struct device *dev,
 
 static void request_gendisk_module(dev_t devt)
 {
+   unsigned int major = MAJOR(devt);
+   struct blk_major_name **n;
+
+   mutex_lock(&major_names_lock);
+   for (n = &major_names[major_to_index(major)]; *n; n = &(*n)->next) {
+   if ((*n)->major == major && (*n)->probe) {
+   (*n)->probe(devt);
+   mutex_unlock(&major_names_lock);
+   return;
+   }
+   }
+   mutex_unlock(&major_names_lock);
+
if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0)
/* Make old-style 2.4 aliases work */
request_module("block-major-%d", MAJOR(devt));
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index c618b27292fcc8..a808afe80a4fec 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -367,7 +367,10 @@ extern void blk_unregister_region(dev_t devt, unsigned 
long range);
 
 #define alloc_disk(minors) alloc_disk_node(minors, NUMA_NO_NODE)
 
-int register_blkdev(unsigned int major, const char *name);
+int __register_blkdev(unsigned int major, const char *name,
+   void (*probe)(dev_t devt));
+#define register_blkdev(major, name) \
+   __register_blkdev(major, name, NULL)
 void unregister_blkdev(unsigned int major, const char *name);
 
 void revalidate_disk_size(struct gendisk *disk, bool verbose);
-- 
2.28.0



[PATCH 03/19] block: cleanup del_gendisk a bit

2020-09-03 Thread Christoph Hellwig
Merge three hidden gendisk checks into one.

Signed-off-by: Christoph Hellwig 
---
 block/genhd.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 44f69f4b2c5aa6..ec9b64207d9c2e 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -948,6 +948,9 @@ void del_gendisk(struct gendisk *disk)
 
might_sleep();
 
+   if (WARN_ON_ONCE(!disk->queue))
+   return;
+
blk_integrity_del(disk);
disk_del_events(disk);
 
@@ -970,20 +973,18 @@ void del_gendisk(struct gendisk *disk)
disk->flags &= ~GENHD_FL_UP;
up_write(&disk->lookup_sem);
 
-   if (!(disk->flags & GENHD_FL_HIDDEN))
+   if (!(disk->flags & GENHD_FL_HIDDEN)) {
sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
-   if (disk->queue) {
+
/*
 * Unregister bdi before releasing device numbers (as they can
 * get reused and we'd get clashes in sysfs).
 */
-   if (!(disk->flags & GENHD_FL_HIDDEN))
-   bdi_unregister(disk->queue->backing_dev_info);
-   blk_unregister_queue(disk);
-   } else {
-   WARN_ON(1);
+   bdi_unregister(disk->queue->backing_dev_info);
}
 
+   blk_unregister_queue(disk);
+   
if (!(disk->flags & GENHD_FL_HIDDEN))
blk_unregister_region(disk_devt(disk), disk->minors);
/*
-- 
2.28.0



Re: [PATCH 1/1] iommu/vt-d: Fix NULL pointer dereference in dev_iommu_priv_set()

2020-09-03 Thread Torsten Hilbrich
On 03.09.20 08:51, Lu Baolu wrote:
> The dev_iommu_priv_set() must be called after probe_device(). This fixes
> a NULL pointer deference bug when booting a system with kernel cmdline
> "intel_iommu=on,igfx_off", where the dev_iommu_priv_set() is abused.
[...]

> 
> Fixes: 01b9d4e21148c ("iommu/vt-d: Use dev_iommu_priv_get/set()")
> Reported-by: Torsten Hilbrich 
> Reported-by: Wendy Wang 
> Link: 
> https://lore.kernel.org/linux-iommu/96717683-70be-7388-3d2f-61131070a...@secunet.com/
> Signed-off-by: Lu Baolu 

Tested-by: Torsten Hilbrich 

Regards,

Torsten


[PATCH 04/19] block: split block_class_lock

2020-09-03 Thread Christoph Hellwig
Split the block_class_lock mutex into one each to protect bdev_map
and major_names.

Signed-off-by: Christoph Hellwig 
---
 block/genhd.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index ec9b64207d9c2e..034e9089965a82 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -25,7 +25,6 @@
 
 #include "blk.h"
 
-static DEFINE_MUTEX(block_class_lock);
 static struct kobject *block_depr;
 
 struct bdev_map {
@@ -37,6 +36,7 @@ struct bdev_map {
int (*lock)(dev_t, void *);
void *data;
 } *bdev_map[255];
+static DEFINE_MUTEX(bdev_map_lock);
 
 /* for extended dynamic devt allocation, currently only one major is used */
 #define NR_EXT_DEVT(1 << MINORBITS)
@@ -400,6 +400,7 @@ static struct blk_major_name {
int major;
char name[16];
 } *major_names[BLKDEV_MAJOR_HASH_SIZE];
+static DEFINE_MUTEX(major_names_lock);
 
 /* index in the above - for now: assume no multimajor ranges */
 static inline int major_to_index(unsigned major)
@@ -412,11 +413,11 @@ void blkdev_show(struct seq_file *seqf, off_t offset)
 {
struct blk_major_name *dp;
 
-   mutex_lock(&block_class_lock);
+   mutex_lock(&major_names_lock);
for (dp = major_names[major_to_index(offset)]; dp; dp = dp->next)
if (dp->major == offset)
seq_printf(seqf, "%3d %s\n", dp->major, dp->name);
-   mutex_unlock(&block_class_lock);
+   mutex_unlock(&major_names_lock);
 }
 #endif /* CONFIG_PROC_FS */
 
@@ -445,7 +446,7 @@ int register_blkdev(unsigned int major, const char *name)
struct blk_major_name **n, *p;
int index, ret = 0;
 
-   mutex_lock(&block_class_lock);
+   mutex_lock(&major_names_lock);
 
/* temporary */
if (major == 0) {
@@ -498,7 +499,7 @@ int register_blkdev(unsigned int major, const char *name)
kfree(p);
}
 out:
-   mutex_unlock(&block_class_lock);
+   mutex_unlock(&major_names_lock);
return ret;
 }
 
@@ -510,7 +511,7 @@ void unregister_blkdev(unsigned int major, const char *name)
struct blk_major_name *p = NULL;
int index = major_to_index(major);
 
-   mutex_lock(&block_class_lock);
+   mutex_lock(&major_names_lock);
for (n = &major_names[index]; *n; n = &(*n)->next)
if ((*n)->major == major)
break;
@@ -520,7 +521,7 @@ void unregister_blkdev(unsigned int major, const char *name)
p = *n;
*n = p->next;
}
-   mutex_unlock(&block_class_lock);
+   mutex_unlock(&major_names_lock);
kfree(p);
 }
 
@@ -671,7 +672,7 @@ void blk_register_region(dev_t devt, unsigned long range, 
struct module *module,
p->data = data;
}
 
-   mutex_lock(&block_class_lock);
+   mutex_lock(&bdev_map_lock);
for (i = 0, p -= n; i < n; i++, p++, index++) {
struct bdev_map **s = &bdev_map[index % 255];
while (*s && (*s)->range < range)
@@ -679,7 +680,7 @@ void blk_register_region(dev_t devt, unsigned long range, 
struct module *module,
p->next = *s;
*s = p;
}
-   mutex_unlock(&block_class_lock);
+   mutex_unlock(&bdev_map_lock);
 }
 EXPORT_SYMBOL(blk_register_region);
 
@@ -690,7 +691,7 @@ void blk_unregister_region(dev_t devt, unsigned long range)
unsigned i;
struct bdev_map *found = NULL;
 
-   mutex_lock(&block_class_lock);
+   mutex_lock(&bdev_map_lock);
for (i = 0; i < min(n, 255u); i++, index++) {
struct bdev_map **s;
for (s = &bdev_map[index % 255]; *s; s = &(*s)->next) {
@@ -703,7 +704,7 @@ void blk_unregister_region(dev_t devt, unsigned long range)
}
}
}
-   mutex_unlock(&block_class_lock);
+   mutex_unlock(&bdev_map_lock);
kfree(found);
 }
 EXPORT_SYMBOL(blk_unregister_region);
@@ -1039,7 +1040,7 @@ static struct gendisk *lookup_gendisk(dev_t dev, int 
*partno)
unsigned long best = ~0UL;
 
 retry:
-   mutex_lock(&block_class_lock);
+   mutex_lock(&bdev_map_lock);
for (p = bdev_map[MAJOR(dev) % 255]; p; p = p->next) {
struct kobject *(*probe)(dev_t, int *, void *);
struct module *owner;
@@ -1060,7 +1061,7 @@ static struct gendisk *lookup_gendisk(dev_t dev, int 
*partno)
module_put(owner);
continue;
}
-   mutex_unlock(&block_class_lock);
+   mutex_unlock(&bdev_map_lock);
kobj = probe(dev, partno, data);
/* Currently ->owner protects _only_ ->probe() itself. */
module_put(owner);
@@ -1068,7 +1069,7 @@ static struct gendisk *lookup_gendisk(dev_t dev, int 
*partno)
return dev_to_disk(kobj_to_dev(kobj));
goto retry;

[PATCH v8 0/6] Support running driver's probe for a device powered off

2020-09-03 Thread Sakari Ailus


Hi all,

These patches enable calling (and finishing) a driver's probe function
without powering on the respective device on busses where the practice is
to power on the device for probe. While it generally is a driver's job to
check the that the device is there, there are cases where it might be
undesirable. (In this case it stems from a combination of hardware design
and user expectations; see below.) The downside with this change is that
if there is something wrong with the device, it will only be found at the
time the device is used. In this case (the camera sensors + EEPROM in a
sensor) I don't see any tangible harm from that though.

An indication both from the driver and the firmware is required to allow
the device's power state to remain off during probe (see the first patch).


The use case is such that there is a privacy LED next to an integrated
user-facing laptop camera, and this LED is there to signal the user that
the camera is recording a video or capturing images. That LED also happens
to be wired to one of the power supplies of the camera, so whenever you
power on the camera, the LED will be lit, whether images are captured from
the camera --- or not. There's no way to implement this differently
without additional software control (allowing of which is itself a
hardware design decision) on most CSI-2-connected camera sensors as they
simply have no pin to signal the camera streaming state.

This is also what happens during driver probe: the camera will be powered
on by the I²C subsystem calling dev_pm_domain_attach() and the device is
already powered on when the driver's own probe function is called. To the
user this visible during the boot process as a blink of the privacy LED,
suggesting that the camera is recording without the user having used an
application to do that. From the end user's point of view the behaviour is
not expected and for someone unfamiliar with internal workings of a
computer surely seems quite suspicious --- even if images are not being
actually captured.

I've tested these on linux-next master. They also apply to Wolfram's
i2c/for-next branch, there's a patch that affects the I²C core changes
here (see below). The patches apart from that apply to Bartosz's
at24/for-next as well as Mauro's linux-media master branch.

since v7 
https://lore.kernel.org/linux-acpi/20200901210333.8462-1-sakari.ai...@linux.intel.com/>:

- Reorder documentation patch right after the implemenation in the I²C
  framework.

- Rename allow-low-power-probe property as i2c-allow-low-power-probe.

- Remove extra "property" from the description of the
  i2c-allow-low-power-probe property and mention it's a device property.

- Add an example to the documentation and refer to the _DSD property spec.

since v6 
https://lore.kernel.org/linux-acpi/20200826115432.6103-1-sakari.ai...@linux.intel.com/>:

- Use u32 for the flags field in struct i2c_driver.

- Use acpi_dev_get_property to read the allow-low-power-probe property.

since v5 
https://lore.kernel.org/linux-acpi/20200810142747.12400-1-sakari.ai...@linux.intel.com/>:

- Identify sensors when they're first powered on. In previous versions, if
  this wasn't in probe, it was not done at all.

- Return allow_low_power_probe() only for ACPI devices, i.e. OF systems
  are not affected by these changes.

- Document that I2C_DRV_FL_ALLOW_LOW_POWER_PROBE flag only applies to ACPI
  drivers.

- Fix extra regulator_disable in at24 driver's remove function when the
  device was already in low power state.

since v4 
https://lore.kernel.org/linux-acpi/20200121134157.20396-1-sakari.ai...@linux.intel.com/>:

- Rename "probe-low-power" property as "allow-low-power-probe". This is
  taken into account in function and file naming, too.

- Turn probe_low_power field in struct i2c_driver into flags field.

- Rebase on Wolfram's i2c/for-next branch that contains the removal of the
  support for disabling I²C core IRQ mappings (commit
  0c2a34937f7e4c4776bb261114c475392da2355c).

- Change wording for "allow-low-power-probe" property in ACPI
  documentation.

since v3 
https://lore.kernel.org/linux-acpi/20200109154529.19484-1-sakari.ai...@linux.intel.com/T/#t>:

- Rework the 2nd patch based on Rafael's comments

- Rework description of the ACPI low power state helper function,
  according to Rafael's text.

- Rename and rework the same function as
  acpi_dev_state_low_power().

- Reflect the changes in commit message as well.

- Added a patch to document the probe-low-power _DSD property.

since v2 https://patchwork.kernel.org/cover/4255/>:

- Remove extra CONFIG_PM ifdefs; these are not needed.

- Move the checks for power state hints from drivers/base/dd.c to
  drivers/i2c/i2c-base-core.c; these are I²C devices anyway.

- Move the probe_low_power field from struct device_driver to struct
  i2c_driver.

since v1:

- Rename probe_powered_off struct device field as probe_low_power and
  reflect the similar naming to the patc

[PATCH v8 3/6] ACPI: Add a convenience function to tell a device is in low power state

2020-09-03 Thread Sakari Ailus
Add a convenience function to tell whether a device is in low power state,
primarily for use in drivers' probe or remove functions on busses where
the custom is to power on the device for the duration of both.

Returns false on non-ACPI systems.

Suggested-by: Mika Westerberg 
Signed-off-by: Sakari Ailus 
Reviewed-by: Rafael J. Wysocki 
---
 drivers/acpi/device_pm.c | 31 +++
 include/linux/acpi.h |  5 +
 2 files changed, 36 insertions(+)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 94d91c67aeaeb..e3c488d4af0d4 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1344,4 +1344,35 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
return 1;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
+
+/**
+ * acpi_dev_state_low_power - Check the current ACPI power state of a device.
+ * @dev: Physical device the ACPI power state of which to check
+ *
+ * On a system without ACPI, return false. On a system with ACPI, return true 
if
+ * the current ACPI power state of the device is not D0, or false otherwise.
+ *
+ * Note that the power state of a device is not well-defined after it has been
+ * passed to acpi_device_set_power() and before that function returns, so it is
+ * not valid to ask for the ACPI power state of the device in that time frame.
+ */
+bool acpi_dev_state_low_power(struct device *dev)
+{
+   struct acpi_device *adev = ACPI_COMPANION(dev);
+   int power_state;
+   int ret;
+
+   if (!adev)
+   return false;
+
+   ret = acpi_device_get_power(adev, &power_state);
+   if (ret) {
+   dev_dbg(dev, "Cannot obtain power state (%d)\n", ret);
+   return false;
+   }
+
+   return power_state != ACPI_STATE_D0;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_state_low_power);
+
 #endif /* CONFIG_PM */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 17e80e182802e..d76d851259a49 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -978,6 +978,7 @@ int acpi_dev_resume(struct device *dev);
 int acpi_subsys_runtime_suspend(struct device *dev);
 int acpi_subsys_runtime_resume(struct device *dev);
 int acpi_dev_pm_attach(struct device *dev, bool power_on);
+bool acpi_dev_state_low_power(struct device *dev);
 #else
 static inline int acpi_dev_runtime_suspend(struct device *dev) { return 0; }
 static inline int acpi_dev_runtime_resume(struct device *dev) { return 0; }
@@ -987,6 +988,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, 
bool power_on)
 {
return 0;
 }
+static inline bool acpi_dev_state_low_power(struct device *dev)
+{
+   return false;
+}
 #endif
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
-- 
2.20.1



Re: [PATCH v4 1/4] mm/pageblock: mitigation cmpxchg false sharing in pageblock flags

2020-09-03 Thread David Hildenbrand
On 03.09.20 09:01, Alex Shi wrote:
> pageblock_flags is used as long, since every pageblock_flags is just 4
> bits, 'long' size will include 8(32bit machine) or 16 pageblocks' flags,
> that flag setting has to sync in cmpxchg with 7 or 15 other pageblock
> flags. It would cause long waiting for sync.
> 
> If we could change the pageblock_flags variable as char, we could use
> char size cmpxchg, which just sync up with 2 pageblock flags. it could
> relief the false sharing in cmpxchg.
> 
> Signed-off-by: Alex Shi 
> Cc: Andrew Morton 
> Cc: Mel Gorman 
> Cc: linux...@kvack.org
> Cc: linux-kernel@vger.kernel.org

Could you please

1. Send a cover letter and indicate the changees between versions. I
cannot find any in my mailbox or on -mm - is there any? (also, is there
a patch 4 ?)

2. Report proper performance numbers as requested, especially, over
multiple runs. This should go into patch 1/2. Are they buried somewhere?

3. Clarify what patch 3 does: Do we actually waste 8*sizeof(long) where
we only need 4 bits?

Also, breaking stuff in patch 1 and fixing it in patch 3 is not
acceptable. This breaks git bisect. Skimming over the patches I think
this is the case.

I am not convinced yet that we need and want this. As Alex mentioned, we
touch pageblock flags while holding the zone lock already in most cases
-  and as Mel mentiones, updates should be rare.

-- 
Thanks,

David / dhildenb



Re: [PATCH 2/9] block: add a bdev_is_partition helper

2020-09-03 Thread Ulf Hansson
On Thu, 3 Sep 2020 at 07:42, Christoph Hellwig  wrote:
>
> Add a littler helper to make the somewhat arcane bd_contains checks a
> little more obvious.
>
> Signed-off-by: Christoph Hellwig 

Not sure why we have both "bd_contains" and "bd_partno", nevertheless,
feel free to add:

Acked-by: Ulf Hansson 

Kind regards
Uffe

> ---
>  block/blk-lib.c | 2 +-
>  block/ioctl.c   | 4 ++--
>  block/scsi_ioctl.c  | 2 +-
>  drivers/ide/ide-ioctls.c| 4 ++--
>  drivers/md/dm-table.c   | 2 +-
>  drivers/mmc/core/block.c| 2 +-
>  drivers/s390/block/dasd_ioctl.c | 8 
>  fs/nfsd/blocklayout.c   | 4 ++--
>  include/linux/blkdev.h  | 9 +++--
>  kernel/trace/blktrace.c | 2 +-
>  10 files changed, 22 insertions(+), 17 deletions(-)
>
> diff --git a/block/blk-lib.c b/block/blk-lib.c
> index 0d1811e57ac704..e90614fd8d6a42 100644
> --- a/block/blk-lib.c
> +++ b/block/blk-lib.c
> @@ -64,7 +64,7 @@ int __blkdev_issue_discard(struct block_device *bdev, 
> sector_t sector,
> return -EINVAL;
>
> /* In case the discard request is in a partition */
> -   if (bdev->bd_partno)
> +   if (bdev_is_partition(bdev))
> part_offset = bdev->bd_part->start_sect;
>
> while (nr_sects) {
> diff --git a/block/ioctl.c b/block/ioctl.c
> index bdb3bbb253d9f8..e4af3df9d28a68 100644
> --- a/block/ioctl.c
> +++ b/block/ioctl.c
> @@ -23,7 +23,7 @@ static int blkpg_do_ioctl(struct block_device *bdev,
> return -EACCES;
> if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
> return -EFAULT;
> -   if (bdev != bdev->bd_contains)
> +   if (bdev_is_partition(bdev))
> return -EINVAL;
>
> if (p.pno <= 0)
> @@ -94,7 +94,7 @@ static int blkdev_reread_part(struct block_device *bdev)
>  {
> int ret;
>
> -   if (!disk_part_scan_enabled(bdev->bd_disk) || bdev != 
> bdev->bd_contains)
> +   if (!disk_part_scan_enabled(bdev->bd_disk) || bdev_is_partition(bdev))
> return -EINVAL;
> if (!capable(CAP_SYS_ADMIN))
> return -EACCES;
> diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
> index ef722f04f88a93..3bb4571385ce21 100644
> --- a/block/scsi_ioctl.c
> +++ b/block/scsi_ioctl.c
> @@ -854,7 +854,7 @@ EXPORT_SYMBOL(scsi_cmd_ioctl);
>
>  int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
>  {
> -   if (bd && bd == bd->bd_contains)
> +   if (bd && !bdev_is_partition(bd))
> return 0;
>
> if (capable(CAP_SYS_RAWIO))
> diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
> index 09491098047bff..58994da10c0664 100644
> --- a/drivers/ide/ide-ioctls.c
> +++ b/drivers/ide/ide-ioctls.c
> @@ -49,7 +49,7 @@ int ide_setting_ioctl(ide_drive_t *drive, struct 
> block_device *bdev,
> return err >= 0 ? put_user_long(err, arg) : err;
>
>  set_val:
> -   if (bdev != bdev->bd_contains)
> +   if (bdev_is_partition(bdev))
> err = -EINVAL;
> else {
> if (!capable(CAP_SYS_ADMIN))
> @@ -257,7 +257,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct 
> block_device *bdev,
> switch (cmd) {
> case HDIO_OBSOLETE_IDENTITY:
> case HDIO_GET_IDENTITY:
> -   if (bdev != bdev->bd_contains)
> +   if (bdev_is_partition(bdev))
> return -EINVAL;
> return ide_get_identity_ioctl(drive, cmd, argp);
> case HDIO_GET_NICE:
> diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
> index 5edc3079e7c199..af156256e511ff 100644
> --- a/drivers/md/dm-table.c
> +++ b/drivers/md/dm-table.c
> @@ -903,7 +903,7 @@ static int device_is_rq_stackable(struct dm_target *ti, 
> struct dm_dev *dev,
> struct request_queue *q = bdev_get_queue(bdev);
>
> /* request-based cannot stack on partitions! */
> -   if (bdev != bdev->bd_contains)
> +   if (bdev_is_partition(bdev))
> return false;
>
> return queue_is_mq(q);
> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> index fa313b63413547..8d3df0be0355ce 100644
> --- a/drivers/mmc/core/block.c
> +++ b/drivers/mmc/core/block.c
> @@ -723,7 +723,7 @@ static int mmc_blk_check_blkdev(struct block_device *bdev)
>  * whole block device, not on a partition.  This prevents overspray
>  * between sibling partitions.
>  */
> -   if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains))
> +   if (!capable(CAP_SYS_RAWIO) || bdev_is_partition(bdev))
> return -EPERM;
> return 0;
>  }
> diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
> index faaf5596e31c12..cb6427fb9f3d16 100644
> --- a/drivers/s390/block/dasd_ioctl.c
> +++ b/drivers/s390/block/dasd_ioctl.c
> @@ -277,7 +277,7 @@ dasd_ioctl_format(struct block_device *bdev, void __user 
> *argp)
> 

Re: [PATCH v2 2/3] remoteproc: qcom: Add capability to collect minidumps

2020-09-03 Thread kernel test robot
Hi Gurbir,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.9-rc3 next-20200902]
[cannot apply to linux/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Gurbir-Arora/Introduce-mini-dump-support-for-remoteproc/20200903-105359
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
fc3abb53250a90ba2150eebd182137c136f4d25a
config: i386-randconfig-m021-20200902 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
# save the attached .config to linux build tree
make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   ld: drivers/remoteproc/remoteproc_coredump.o: in function 
`qcom_rproc_minidump':
>> drivers/remoteproc/remoteproc_coredump.c:498: undefined reference to 
>> `qcom_smem_get'

# 
https://github.com/0day-ci/linux/commit/ff3d7cbd5128989c0f4961ea07d00ef31f2928e3
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Gurbir-Arora/Introduce-mini-dump-support-for-remoteproc/20200903-105359
git checkout ff3d7cbd5128989c0f4961ea07d00ef31f2928e3
vim +498 drivers/remoteproc/remoteproc_coredump.c

   490  
   491  void qcom_rproc_minidump(struct rproc *rproc, unsigned int minidump_id)
   492  {
   493  struct md_ss_toc *minidump_ss;
   494  size_t size;
   495  
   496  /* Get Global minidump ToC*/
   497  if (!g_md_toc)
 > 498  g_md_toc = qcom_smem_get(QCOM_SMEM_HOST_ANY,

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [RESEND PATCH v2] mfd: syscon: Use a unique name with regmap_config

2020-09-03 Thread Marc Zyngier

On 2020-08-27 21:32, Suman Anna wrote:

Hi Marc,

+ Mark Brown

On 8/27/20 3:06 PM, Marc Zyngier wrote:

Hi Suman,

On 2020-08-27 19:28, Suman Anna wrote:

Hi Marc,

On 8/27/20 9:46 AM, Marc Zyngier wrote:


[...]


This patch triggers some illegal memory accesses when debugfs is
enabled, as regmap does rely on config->name to be persistent
when the debugfs registration is deferred via 
regmap_debugfs_early_list
(__regmap_init() -> regmap_attach_dev() -> 
regmap_debugfs_init()...),

leading to a KASAN splat on demand.



Thanks, I missed the subtlety around the debugfs registration.


I came up with the following patch that solves the issue for me.

Thanks,

    M.

From fd3f5f2bf72df53be18d13914fe349a34f81f16b Mon Sep 17 00:00:00 
2001

From: Marc Zyngier 
Date: Thu, 27 Aug 2020 14:45:34 +0100
Subject: [PATCH] mfd: syscon: Don't free allocated name for 
regmap_config


The name allocated for the regmap_config structure is freed
pretty early, right after the registration of the MMIO region.

Unfortunately, that doesn't follow the life cycle that debugfs
expects, as it can access the name field long after the free
has occured.

Move the free on the error path, and keep it forever otherwise.


Hmm, this is exactly what I was trying to avoid. The regmap_init does 
duplicate
the name into map->name if config->name is given, and the regmap 
debugfs makes
another copy of its own into debugfs_name when actually registered. 
If the rules
for regmap_init is that the config->name should be persistent, then I 
guess we

have no choice but to go with the below fix.

Does something like below help?

diff --git a/drivers/base/regmap/regmap.c 
b/drivers/base/regmap/regmap.c

index e93700af7e6e..96d8a0161c89 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1137,7 +1137,7 @@ struct regmap *__regmap_init(struct device 
*dev,

    if (ret != 0)
    goto err_regcache;
    } else {
-   regmap_debugfs_init(map, config->name);
+   regmap_debugfs_init(map, map->name);

But there are couple of other places in regmap code that uses 
config->name, but

those won't be exercised with the syscon code.


Is config->name always the same as map->name? If so, why don't you 
just

pass map once and for all? Is the lifetime of map->name the same as
that of config->name?


map->name is created (kstrdup_const) from config->name if not NULL, so 
above
replacement should be exactly equivalent, map is filled in 
_regmap_init. But it
does make the regmap_debugfs_init callsites in the file look 
dissimilar.




My worry with this approach is that we start changing stuff in a rush,
and this would IMHO deserve a thorough investigation of whether this
change is actually safe.

I'd rather take the safe approach of either keeping the memory around
until we clearly understand what the implications are (and probably
this should involve the regmap maintainer), or to revert this patch
until we figure out the actual life cycle of the various names.


Yeah, agreed. Let's see what Mark suggests.

Mark,
Can you clarify the lifecycle expectations on the config->name and do 
you have

any suggestions here?


Have we reached a conclusion here? Can we get a fix in mainline?

Thanks,

M.
--
Jazz is not dead. It just smells funny...


Re: [PATCH 2/9] block: add a bdev_is_partition helper

2020-09-03 Thread Christoph Hellwig
On Thu, Sep 03, 2020 at 10:19:34AM +0200, Ulf Hansson wrote:
> On Thu, 3 Sep 2020 at 07:42, Christoph Hellwig  wrote:
> >
> > Add a littler helper to make the somewhat arcane bd_contains checks a
> > little more obvious.
> >
> > Signed-off-by: Christoph Hellwig 
> 
> Not sure why we have both "bd_contains" and "bd_partno", nevertheless,
> feel free to add:

Right now both are needed for how blkdev_get/put work.  But I plan to
eventual kill off bd_contains after some major surgery to that code.



Re: [PATCH v3 0/2] MIPS: Add support for ZSTD v3

2020-09-03 Thread Thomas Bogendoerfer
On Tue, Sep 01, 2020 at 04:26:49PM +0200, Paul Cercueil wrote:
> Hi,
> 
> This small patchset adds support for self-extracting kernels compressed
> with ZSTD.
> 
> Nick:
> I dropped your Reviewed-by on patch [1/2] since the code changed.
> 
> Cheers,
> -Paul
> 
> Paul Cercueil (2):
>   lib: decompress_unzstd: Limit output size
>   MIPS: Add support for ZSTD-compressed kernels
> 
>  arch/mips/Kconfig  |  1 +
>  arch/mips/boot/compressed/Makefile |  3 ++-
>  arch/mips/boot/compressed/decompress.c |  4 
>  arch/mips/boot/compressed/string.c | 17 +
>  lib/decompress_unzstd.c|  7 ++-
>  5 files changed, 30 insertions(+), 2 deletions(-)

series applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: perf: Fix wrong check condition of Loongson event IDs

2020-09-03 Thread Thomas Bogendoerfer
On Thu, Aug 27, 2020 at 04:03:08PM +0800, Tiezhu Yang wrote:
> According to the user's manual chapter 8.2.1 of Loongson 3A2000 CPU [1]
> and 3A3000 CPU [2], we should take some event IDs such as 274, 358, 359
> and 360 as valid in the check condition, otherwise they are recognized
> as "not supported", fix it.
> 
> [1] http://www.loongson.cn/uploadfile/cpu/3A2000/Loongson3A2000_user2.pdf
> [2] 
> http://www.loongson.cn/uploadfile/cpu/3A3000/Loongson3A3000_3B3000user2.pdf
> 
> Fixes: e9dfbaaeef1c ("MIPS: perf: Add hardware perf events support for new 
> Loongson-3")
> Signed-off-by: Tiezhu Yang 
> ---
>  arch/mips/kernel/perf_event_mipsxx.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

applied to mips-fixes.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [RESEND PATCH v2] dt-bindings: renesas,rcar-dmac: Document r8a7742 support

2020-09-03 Thread Vinod Koul
On 03-09-20, 08:38, Lad Prabhakar wrote:
> Renesas RZ/G SoC also have the R-Car gen2/3 compatible DMA controllers.
> Document RZ/G1H (also known as R8A7742) SoC bindings.

Applied, thanks

-- 
~Vinod


Re: [PATCH] MIPS: SNI: Fix SCSI interrupt

2020-09-03 Thread Thomas Bogendoerfer
On Wed, Sep 02, 2020 at 11:32:14PM +0200, Thomas Bogendoerfer wrote:
> On RM400(a20r) machines ISA and SCSI interrupts share the same interrupt
> line. Commit 49e6e07e3c80 ("MIPS: pass non-NULL dev_id on shared
> request_irq()") accidently dropped the IRQF_SHARED bit, which breaks
> registering SCSI interrupt. Put back IRQF_SHARED and add dev_id for
> ISA interrupt.
> 
> Fixes: 49e6e07e3c80 ("MIPS: pass non-NULL dev_id on shared request_irq()")
> Signed-off-by: Thomas Bogendoerfer 
> ---
>  arch/mips/sni/a20r.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

applied ti mips-fixes.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: Use rcu to lookup a task in mipsmt_sys_sched_setaffinity()

2020-09-03 Thread Thomas Bogendoerfer
On Mon, Aug 31, 2020 at 01:14:02PM -0700, Davidlohr Bueso wrote:
> The call simply looks up the corresponding task (without iterating
> the tasklist), which is safe under rcu instead of the tasklist_lock.
> In addition, the setaffinity counter part already does this.
> 
> Signed-off-by: Davidlohr Bueso 
> ---
>  arch/mips/kernel/mips-mt-fpaff.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH 00/11] mmc: Minor cleanups and compile test

2020-09-03 Thread Krzysztof Kozlowski
On Thu, 3 Sep 2020 at 10:10, Ulf Hansson  wrote:
>
> Series applied for next, except 11, thanks!

Thanks. I will fix pointed compile-test issues and send later a follow
up, also removing the MMC dependency as pointed by Michał.

Best regards,
Krzysztof


Re: [PATCH v2 1/2] mm: use add_page_to_lru_list()/page_lru()/page_off_lru()

2020-09-03 Thread Michal Hocko
On Mon 31-08-20 11:50:41, Yu Zhao wrote:
[...]
> @@ -1860,16 +1859,11 @@ static unsigned noinline_for_stack 
> move_pages_to_lru(struct lruvec *lruvec,
>   lruvec = mem_cgroup_page_lruvec(page, pgdat);
>  
>   SetPageLRU(page);
> - lru = page_lru(page);
> -
> - nr_pages = thp_nr_pages(page);
> - update_lru_size(lruvec, lru, page_zonenum(page), nr_pages);
> - list_move(&page->lru, &lruvec->lists[lru]);
> + add_page_to_lru_list(page, lruvec, page_lru(page));
>  
>   if (put_page_testzero(page)) {
>   __ClearPageLRU(page);
> - __ClearPageActive(page);

This should go into its own patch. The rest is a mechanical and clear.
This one needs some head scratching. E.g. Is it correct for all compound
pages. I believe it should be but few words on why would be better.

> - del_page_from_lru_list(page, lruvec, lru);
> + del_page_from_lru_list(page, lruvec, 
> page_off_lru(page));
>  
>   if (unlikely(PageCompound(page))) {
>   spin_unlock_irq(&pgdat->lru_lock);
> @@ -1878,6 +1872,7 @@ static unsigned noinline_for_stack 
> move_pages_to_lru(struct lruvec *lruvec,
>   } else
>   list_add(&page->lru, &pages_to_free);
>   } else {
> + nr_pages = thp_nr_pages(page);
>   nr_moved += nr_pages;
>   if (PageActive(page))
>   workingset_age_nonresident(lruvec, nr_pages);
> -- 
> 2.28.0.402.g5ffc5be6b7-goog
> 

-- 
Michal Hocko
SUSE Labs


[PATCH] dasd: remove the unused dasd_enable_device export

2020-09-03 Thread Christoph Hellwig
Signed-off-by: Christoph Hellwig 
---
 drivers/s390/block/dasd.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index eb17fea8075c6f..6ab992b3eed004 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -683,7 +683,6 @@ void dasd_enable_device(struct dasd_device *device)
if (device->discipline->kick_validate)
device->discipline->kick_validate(device);
 }
-EXPORT_SYMBOL(dasd_enable_device);
 
 /*
  * SECTION: device operation (interrupt handler, start i/o, term i/o ...)
-- 
2.28.0



Re: [PATCH 3/6] ARM: dts: am335x: lxm: Fix PCA9539 GPIO expander properties

2020-09-03 Thread Tony Lindgren
* Krzysztof Kozlowski  [200829 09:40]:
> The PCA9539 GPIO expander requires GPIO controller properties to operate
> properly.

Best to merge this with the rest of the series:

Acked-by: Tony Lindgren 


Re: [PATCH v4 1/4] mm/pageblock: mitigation cmpxchg false sharing in pageblock flags

2020-09-03 Thread Alex Shi



在 2020/9/3 下午3:24, Mel Gorman 写道:
> On Thu, Sep 03, 2020 at 03:01:20PM +0800, Alex Shi wrote:
>> pageblock_flags is used as long, since every pageblock_flags is just 4
>> bits, 'long' size will include 8(32bit machine) or 16 pageblocks' flags,
>> that flag setting has to sync in cmpxchg with 7 or 15 other pageblock
>> flags. It would cause long waiting for sync.
>>
>> If we could change the pageblock_flags variable as char, we could use
>> char size cmpxchg, which just sync up with 2 pageblock flags. it could
>> relief the false sharing in cmpxchg.
>>
>> Signed-off-by: Alex Shi 
> 
> Page block types were not known to change at high frequency that would
> cause a measurable performance drop. If anything, the performance hit
> from pageblocks is the lookup paths which is a lot more frequent.

Yes, it is not hot path. But it's still a meaningful points to reduce cmpxchg
level false sharing which isn't right on logical.


> 
> What was the workload you were running that altered pageblocks at a high
> enough frequency for collisions to occur when updating adjacent
> pageblocks?
> 

I have run thpscale with 'always' defrag setting of THP. The Amean stddev is 
much
larger than a very little average run time reducing.

But the left patch 4 could show the cmpxchg retry reduce from thousands to 
hundreds
or less.

Subject: [PATCH v4 4/4] add cmpxchg tracing

Signed-off-by: Alex Shi 
---
 include/trace/events/pageblock.h | 30 ++
 mm/page_alloc.c  |  4 
 2 files changed, 34 insertions(+)
 create mode 100644 include/trace/events/pageblock.h

diff --git a/include/trace/events/pageblock.h b/include/trace/events/pageblock.h
new file mode 100644
index ..003c2d716f82
--- /dev/null
+++ b/include/trace/events/pageblock.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM pageblock
+
+#if !defined(_TRACE_PAGEBLOCK_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_PAGEBLOCK_H
+
+#include 
+
+TRACE_EVENT(hit_cmpxchg,
+
+   TP_PROTO(char byte),
+
+   TP_ARGS(byte),
+
+   TP_STRUCT__entry(
+   __field(char, byte)
+   ),
+
+   TP_fast_assign(
+   __entry->byte = byte;
+   ),
+
+   TP_printk("%d", __entry->byte)
+);
+
+#endif /* _TRACE_PAGE_ISOLATION_H */
+
+/* This part must be outside protection */
+#include 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8b65d83d8be6..a6d7159295bc 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -509,6 +509,9 @@ static __always_inline int get_pfnblock_migratetype(struct 
page *page, unsigned
  * @pfn: The target page frame number
  * @mask: mask of bits that the caller is interested in
  */
+#define CREATE_TRACE_POINTS
+#include 
+
 void set_pfnblock_flags_mask(struct page *page, unsigned long flags,
unsigned long pfn,
unsigned long mask)
@@ -532,6 +535,7 @@ void set_pfnblock_flags_mask(struct page *page, unsigned 
long flags,
if (byte == old_byte)
break;
byte = old_byte;
+   trace_hit_cmpxchg(byte);
}
 }

--
1.8.3.1


[PATCH] crypto: s5p-sss: remove redundant null check

2020-09-03 Thread Xu Wang
Because clk_disable_unprepare already checked NULL clock
parameter, so the additional checks are unnecessary, just remove them.

Signed-off-by: Xu Wang 
---
 drivers/crypto/s5p-sss.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c
index 341433fbcc4a..fdcbfd45c884 100644
--- a/drivers/crypto/s5p-sss.c
+++ b/drivers/crypto/s5p-sss.c
@@ -2307,8 +2307,7 @@ static int s5p_aes_probe(struct platform_device *pdev)
tasklet_kill(&pdata->tasklet);
 
 err_irq:
-   if (pdata->pclk)
-   clk_disable_unprepare(pdata->pclk);
+   clk_disable_unprepare(pdata->pclk);
 
 err_clk:
clk_disable_unprepare(pdata->clk);
@@ -2338,8 +2337,7 @@ static int s5p_aes_remove(struct platform_device *pdev)
pdata->use_hash = false;
}
 
-   if (pdata->pclk)
-   clk_disable_unprepare(pdata->pclk);
+   clk_disable_unprepare(pdata->pclk);
 
clk_disable_unprepare(pdata->clk);
s5p_dev = NULL;
-- 
2.17.1



Re: [PATCH v6 00/20] gpio: cdev: add uAPI v2

2020-09-03 Thread Kent Gibson
On Thu, Sep 03, 2020 at 10:02:04AM +0200, Bartosz Golaszewski wrote:
> On Mon, Aug 31, 2020 at 5:21 AM Kent Gibson  wrote:
> >
> > This patchset defines and implements a new version of the
> > GPIO CDEV uAPI to address existing 32/64-bit alignment issues, add
> > support for debounce, event sequence numbers, and allow for requested
> > lines with different configurations.
> > It provides some future proofing by adding optional configuration fields
> > and padding reserved for future use.
> >
> > The series can be partitioned into three blocks; the first two patches
> > are minor fixes that impact later patches, the next eleven contain the
> > v2 uAPI definition and implementation, and the final seven port the GPIO
> > tools to the v2 uAPI and extend them to use new uAPI features.
> >
> > The more complicated patches include their own commentary where
> > appropriate.
> >
> > Cheers,
> > Kent.
> >
> > Changes for v6:
> >  - flags variable in linereq_create() should be u64 not unsigned long
> >(patch 07)
> >  - remove restrictions on configuration changes - any change from one
> >valid state to another valid state is allowed. (patches 09, 10, 12)
> >
> > Changes for v5:
> >
> > All changes for v5 fix issues with the gpiolib-cdev.c implementation,
> > in patches 07-12.
> > The uAPI is unchanged from v4, as is the port of the tools.
> >
> >  - use IS_ALIGNED in BUILD_BUG_ON checks (patch 07)
> >  - relocate BUILD_BUG_ON checks to gpiolib_cdev_register (patch 07)
> >  - s/requies/requires/ (patch 07)
> >  - use unsigned int for variables that are never negative
> >  - change lineinfo_get() parameter from cmd to bool watch (patch 08)
> >  - flagsv2 in gpio_v2_line_info_to_v1() should be u64, not int (patch 08)
> >  - change "_locked" suffixed function names to "_unlocked" (patch 10 and
> >11)
> >  - be less eager breaking long lines
> >  - move commentary into checkin comment where appropriate - particularly
> >patch 12
> >  - restructure the request/line split - rename struct line to
> >struct linereq, and struct edge_detector to struct line, and relocate
> >the desc field from linereq to line.  The linereq name was selected
> >over line_request as function names such as linereq_set_values() are
> >more clearly associated with requests than line_request_set_values(),
> >particularly as there is also a struct line.  And linereq is as
> >informative as linerequest, so I went with the shortened form.
> >
> > Changes for v4:
> >  - bitmap width clarification in gpiod.h (patch 04)
> >  - fix info offset initialisation bug (patch 08 and inserting patch 01)
> >  - replace strncpy with strscpy to remove compiler warnings
> >(patch 08 and inserting patch 02)
> >  - fix mask handling in line_get_values (patch 07)
> >
> > Changes for v3:
> >  - disabling the character device from the build requires EXPERT
> >  - uAPI revisions (see patch 02)
> >  - replace padding_not_zeroed with calls to memchr_inv
> >  - don't use bitops on 64-bit flags as that doesn't work on BE-32
> >  - accept first attribute matching a line in gpio_v2_line_config.attrs
> >rather than the last
> >  - rework lsgpio port to uAPI v2 as flags reverted to v1 like layout
> >(since patch v2)
> >  - swapped patches 17 and 18 to apply debounce to multiple monitored
> >lines
> >
> > Changes for v2:
> >  - split out cleanup patches into a separate series.
> >  - split implementation patch into a patch for each ioctl or major feature.
> >  - split tool port patch into a patch per tool.
> >  - rework uAPI to allow requested lines with different configurations.
> >
> > Kent Gibson (20):
> >   gpiolib: cdev: desc_to_lineinfo should set info offset
> >   gpiolib: cdev: replace strncpy with strscpy
> >   gpio: uapi: define GPIO_MAX_NAME_SIZE for array sizes
> >   gpio: uapi: define uAPI v2
> >   gpiolib: make cdev a build option
> >   gpiolib: add build option for CDEV v1 ABI
> >   gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and
> > GPIO_V2_LINE_GET_VALUES_IOCTL
> >   gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and
> > GPIO_V2_GET_LINEINFO_WATCH_IOCTL
> >   gpiolib: cdev: support edge detection for uAPI v2
> >   gpiolib: cdev: support GPIO_V2_LINE_SET_CONFIG_IOCTL
> >   gpiolib: cdev: support GPIO_V2_LINE_SET_VALUES_IOCTL
> >   gpiolib: cdev: support setting debounce
> >   gpio: uapi: document uAPI v1 as deprecated
> >   tools: gpio: port lsgpio to v2 uAPI
> >   tools: gpio: port gpio-watch to v2 uAPI
> >   tools: gpio: rename nlines to num_lines
> >   tools: gpio: port gpio-hammer to v2 uAPI
> >   tools: gpio: port gpio-event-mon to v2 uAPI
> >   tools: gpio: add multi-line monitoring to gpio-event-mon
> >   tools: gpio: add debounce support to gpio-event-mon
> >
> >  drivers/gpio/Kconfig|   29 +-
> >  drivers/gpio/Makefile   |2 +-
> >  drivers/gpio/gpiolib-cdev.c | 1273 +--
> >  drivers/gpio/gpiolib-cdev.h |   15 +
> >  drivers/gpio/gpiolib.c 

[PATCH] Bluetooth: hci_qca: remove redundant null check

2020-09-03 Thread Xu Wang
Because clk_disable_unprepare already checked
NULL clock parameter, so the additional check is
unnecessary, just remove it.

Signed-off-by: Xu Wang 
---
 drivers/bluetooth/hci_qca.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 20e1dedbc58c..6577356d849b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -2007,8 +2007,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
if (err) {
BT_ERR("Rome serdev registration failed");
-   if (qcadev->susclk)
-   clk_disable_unprepare(qcadev->susclk);
+   clk_disable_unprepare(qcadev->susclk);
return err;
}
}
-- 
2.17.1



INFO: task hung in io_uring_setup

2020-09-03 Thread syzbot
Hello,

syzbot found the following issue on:

HEAD commit:4442749a Add linux-next specific files for 20200902
git tree:   linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=12f9e91590
kernel config:  https://syzkaller.appspot.com/x/.config?x=39134fcec6c78e33
dashboard link: https://syzkaller.appspot.com/bug?extid=107dd59d1efcaf3ffca4
compiler:   gcc (GCC) 10.1.0-syz 20200507
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=1159467190
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=111ca83590

The issue was bisected to:

commit dfe127799f8e663c7e3e48b5275ca538b278177b
Author: Stefano Garzarella 
Date:   Thu Aug 27 14:58:31 2020 +

io_uring: allow disabling rings during the creation

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=11bc66c190
final oops: https://syzkaller.appspot.com/x/report.txt?x=13bc66c190
console output: https://syzkaller.appspot.com/x/log.txt?x=15bc66c190

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+107dd59d1efcaf3ff...@syzkaller.appspotmail.com
Fixes: dfe127799f8e ("io_uring: allow disabling rings during the creation")

INFO: task syz-executor047:6853 blocked for more than 143 seconds.
  Not tainted 5.9.0-rc3-next-20200902-syzkaller #0
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:syz-executor047 state:D stack:28104 pid: 6853 ppid:  6847 flags:0x4000
Call Trace:
 context_switch kernel/sched/core.c:3777 [inline]
 __schedule+0xea9/0x2230 kernel/sched/core.c:4526
 schedule+0xd0/0x2a0 kernel/sched/core.c:4601
 schedule_timeout+0x1d8/0x250 kernel/time/timer.c:1855
 do_wait_for_common kernel/sched/completion.c:85 [inline]
 __wait_for_common kernel/sched/completion.c:106 [inline]
 wait_for_common kernel/sched/completion.c:117 [inline]
 wait_for_completion+0x163/0x260 kernel/sched/completion.c:138
 io_sq_thread_stop fs/io_uring.c:6906 [inline]
 io_finish_async fs/io_uring.c:6920 [inline]
 io_sq_offload_create fs/io_uring.c:7595 [inline]
 io_uring_create fs/io_uring.c:8671 [inline]
 io_uring_setup+0x1495/0x29a0 fs/io_uring.c:8744
 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x440299
Code: Bad RIP value.
RSP: 002b:7ffc57cff668 EFLAGS: 0246 ORIG_RAX: 01a9
RAX: ffda RBX: 004002c8 RCX: 00440299
RDX: 00400b40 RSI: 2100 RDI: 3ffe
RBP: 006ca018 R08:  R09: 
R10:  R11: 0246 R12: 00401aa0
R13: 00401b30 R14:  R15: 
INFO: task io_uring-sq:6854 blocked for more than 143 seconds.
  Not tainted 5.9.0-rc3-next-20200902-syzkaller #0
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:io_uring-sq state:D stack:31200 pid: 6854 ppid: 2 flags:0x4000
Call Trace:
 context_switch kernel/sched/core.c:3777 [inline]
 __schedule+0xea9/0x2230 kernel/sched/core.c:4526
 schedule+0xd0/0x2a0 kernel/sched/core.c:4601
 schedule_preempt_disabled+0xf/0x20 kernel/sched/core.c:4660
 kthread+0x2ac/0x4a0 kernel/kthread.c:285
 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:294

Showing all locks held in the system:
1 lock held by khungtaskd/1174:
 #0: 89c67980 (rcu_read_lock){}-{1:2}, at: 
debug_show_all_locks+0x53/0x260 kernel/locking/lockdep.c:5829
3 locks held by in:imklog/6525:
 #0: 8880a3de2df0 (&f->f_pos_lock){+.+.}-{3:3}, at: __fdget_pos+0xe9/0x100 
fs/file.c:930
 #1: 8880907d8968 (&mm->mmap_lock#2){}-{3:3}, at: rq_lock 
kernel/sched/sched.h:1292 [inline]
 #1: 8880907d8968 (&mm->mmap_lock#2){}-{3:3}, at: ttwu_queue 
kernel/sched/core.c:2698 [inline]
 #1: 8880907d8968 (&mm->mmap_lock#2){}-{3:3}, at: 
try_to_wake_up+0x52b/0x12b0 kernel/sched/core.c:2978
 #2: 8880ae620ec8 (&per_cpu_ptr(group->pcpu, cpu)->seq){-.-.}-{0:0}, at: 
psi_task_switch+0x2fb/0x400 kernel/sched/psi.c:833

=

NMI backtrace for cpu 1
CPU: 1 PID: 1174 Comm: khungtaskd Not tainted 5.9.0-rc3-next-20200902-syzkaller 
#0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 
01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x198/0x1fd lib/dump_stack.c:118
 nmi_cpu_backtrace.cold+0x44/0xd7 lib/nmi_backtrace.c:105
 nmi_trigger_cpumask_backtrace+0x1b3/0x223 lib/nmi_backtrace.c:62
 trigger_all_cpu_backtrace include/linux/nmi.h:147 [inline]
 check_hung_uninterruptible_tasks kernel/hung_task.c:253 [inline]
 watchdog+0xd89/0xf30 kernel/hung_task.c:339
 kthread+0x3b5/0x4a0 kernel/kthread.c:292
 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:294
Sending NMI from CPU 1 to CPUs 0:
NMI backtrace for cpu 0
CPU: 0 PID: 3901 Comm: systemd-journal Not tainted 
5.9.0-rc3-next-20200902-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute 

Re: linux-next: Tree for Aug 26

2020-09-03 Thread Anders Roxell
Hi Paul,

On Sat, 29 Aug 2020 at 00:59, Paul E. McKenney  wrote:
>
> On Fri, Aug 28, 2020 at 09:24:19PM +0200, Anders Roxell wrote:
> > On Fri, 28 Aug 2020 at 15:29, Paul E. McKenney  wrote:
> > >
> > > On Fri, Aug 28, 2020 at 09:37:17AM +0200, Anders Roxell wrote:
> > > > On Wed, 26 Aug 2020 at 21:39, Paul E. McKenney  
> > > > wrote:
> > > > >
> > > > > On Wed, Aug 26, 2020 at 08:19:01PM +0200, Anders Roxell wrote:
> > > > > > On Wed, 26 Aug 2020 at 08:33, Stephen Rothwell 
> > > > > >  wrote:
> > > > >
> > > > > [ . . . ]
> > > > >
> > > > > > I've built and run an arm64 allmodconfig kernel where I use the
> > > > > > defconfig as the base, I do this for testing purposes.
> > > > > > I can see the following call trace [1]:
> > > > > >
> > > > > > [ 2595.811453][T1] Running tests on all trace events:
> > > > > > [ 2595.860933][T1] Testing all events:
> > > > > > [ 4316.066072][T8] kworker/dying (8) used greatest stack depth:
> > > > > > 27056 bytes left
> > > > > > [ 8561.924871][C0] watchdog: BUG: soft lockup - CPU#0 stuck for
> > > > > > 22s! [migration/0:14]
> > > > > > [ 8561.934498][C0] Modules linked in:
> > > > > > [ 8561.942303][C0] irq event stamp: 4044
> > > > > > [ 8561.949044][C0] hardirqs last  enabled at (4043):
> > > > > > [] _raw_spin_unlock_irqrestore+0xac/0x138
> > > > > > [ 8561.960848][C0] hardirqs last disabled at (4044):
> > > > > > [] __schedule+0xf8/0x7e0
> > > > > > [ 8561.971418][C0] softirqs last  enabled at (3698):
> > > > > > [] __do_softirq+0x524/0x5f8
> > > > > > [ 8561.982191][C0] softirqs last disabled at (3689):
> > > > > > [] __irq_exit_rcu+0x128/0x1a0
> > > > > > [ 8561.993068][C0] CPU: 0 PID: 14 Comm: migration/0 Tainted: G
> > > > > >W 5.9.0-rc2-next-20200826-5-g24628bb4c0bf #1
> > > > > > [ 8562.005684][C0] Hardware name: linux,dummy-virt (DT)
> > > > > > [ 8562.013247][C0] pstate: 8045 (Nzcv daif +PAN -UAO 
> > > > > > BTYPE=--)
> > > > > > [ 8562.021657][C0] pc : arch_local_irq_enable+0x58/0x80
> > > > > > [ 8562.029323][C0] lr : _raw_spin_unlock_irq+0x84/0xc0
> > > > > > [ 8562.036739][C0] sp : 698efaa0
> > > > > > [ 8562.042984][C0] x29: 698efaa0 x28: 6ad0f270
> > > > > > [ 8562.053814][C0] x27: 6ad0f248 x26: 698d4718
> > > > > > [ 8562.064687][C0] x25: 6ad0e798 x24: a000139e3a40
> > > > > > [ 8562.075506][C0] x23: 0001 x22: a000154f5000
> > > > > > [ 8562.086425][C0] x21: 6ad0e798 x20: 6ad0e780
> > > > > > [ 8562.097255][C0] x19: a000126a905c x18: 14c0
> > > > > > [ 8562.108071][C0] x17: 1500 x16: 1440
> > > > > > [ 8562.118918][C0] x15: f1f1f1f1 x14: 003d0900
> > > > > > [ 8562.129739][C0] x13: 3d09 x12: 8d31df41
> > > > > > [ 8562.140544][C0] x11: 1fffed31df40 x10: 8d31df40
> > > > > > [ 8562.151366][C0] x9 : dfffa000 x8 : 698efa07
> > > > > > [ 8562.162247][C0] x7 : 0001 x6 : 72ce20c0
> > > > > > [ 8562.173072][C0] x5 : 698d4040 x4 : dfffa000
> > > > > > [ 8562.183954][C0] x3 : a0001040f904 x2 : 0007
> > > > > > [ 8562.194811][C0] x1 : a0001408 x0 : 00e0
> > > > > > [ 8562.205858][C0] Call trace:
> > > > > > [ 8562.211739][C0]  arch_local_irq_enable+0x58/0x80
> > > > > > [ 8562.219076][C0]  _raw_spin_unlock_irq+0x84/0xc0
> > > > > > [ 8562.226394][C0]  __schedule+0x75c/0x7e0
> > > > > > [ 8562.233074][C0]  preempt_schedule_notrace+0x64/0xc0
> > > > > > [ 8562.268210][C0]  ftrace_ops_list_func+0x494/0x4e0
> > > > > > [ 8562.275735][C0]  ftrace_graph_call+0x0/0x4
> > > > > > [ 8562.282647][C0]  preempt_count_add+0xc/0x240
> > > > > > [ 8562.289686][C0]  schedule+0xe4/0x160
> > > > > > [ 8562.296187][C0]  smpboot_thread_fn+0x47c/0x540
> > > > > > [ 8562.303377][C0]  kthread+0x23c/0x260
> > > > > > [ 8562.309906][C0]  ret_from_fork+0x10/0x18
> > > > > > [ 8562.316604][C0] Kernel panic - not syncing: softlockup: hung 
> > > > > > tasks
> > > > > > [ 8562.325230][C0] CPU: 0 PID: 14 Comm: migration/0 Tainted: G
> > > > > >WL5.9.0-rc2-next-20200826-5-g24628bb4c0bf #1
> > > > > > [ 8562.337861][C0] Hardware name: linux,dummy-virt (DT)
> > > > > > [ 8562.345374][C0] Call trace:
> > > > > > [ 8562.351228][C0]  dump_backtrace+0x0/0x320
> > > > > > [ 8562.358070][C0]  show_stack+0x38/0x60
> > > > > > [ 8562.364728][C0]  dump_stack+0x1c0/0x280
> > > > > > [ 8562.371447][C0]  panic+0x32c/0x614
> > > > > > [ 8562.377868][C0]  watchdog_timer_fn+0x49c/0x560
> > > > > > [ 8562.385076][C0]  __run_hrtimer+0x1cc/0x360
> > > > > > [ 8562.392021][C0]  __hrtimer_run_queues+0x1a0/0x220
> > > > > > [ 8562.399500][C0]  hrtimer_interrupt+0x1f8/0x440
> > > > > > [ 8562.406807][

Re: Packet gets stuck in NOLOCK pfifo_fast qdisc

2020-09-03 Thread Paolo Abeni
On Wed, 2020-09-02 at 22:01 -0700, Cong Wang wrote:
> Can you test the attached one-line fix? I think we are overthinking,
> probably all
> we need here is a busy wait.

I think that will solve, but I also think that will kill NOLOCK
performances due to really increased contention.

At this point I fear we could consider reverting the NOLOCK stuff.
I personally would hate doing so, but it looks like NOLOCK benefits are
outweighed by its issues.

Any other opinion more than welcome!

Cheers,

Paolo



Re: [PATCH v2] soundwire: fix double free of dangling pointer

2020-09-03 Thread Vinod Koul
On 02-09-20, 13:26, t...@redhat.com wrote:
> From: Tom Rix 
> 
> clang static analysis flags this problem
> 
> stream.c:844:9: warning: Use of memory after
>   it is freed
> kfree(bus->defer_msg.msg->buf);
>   ^~~
> 
> This happens in an error handler cleaning up memory
> allocated for elements in a list.
> 
>   list_for_each_entry(m_rt, &stream->master_list, stream_node) {
>   bus = m_rt->bus;
> 
>   kfree(bus->defer_msg.msg->buf);
>   kfree(bus->defer_msg.msg);
>   }
> 
> And is triggered when the call to sdw_bank_switch() fails.
> There are a two problems.
> 
> First, when sdw_bank_switch() fails, though it frees memory it
> does not clear bus's reference 'defer_msg.msg' to that memory.
> 
> The second problem is the freeing msg->buf. In some cases
> msg will be NULL so this will dereference a null pointer.
> Need to check before freeing.

Applied, thanks

-- 
~Vinod


Re: [PATCH v4 1/4] mm/pageblock: mitigation cmpxchg false sharing in pageblock flags

2020-09-03 Thread Alex Shi



在 2020/9/3 下午4:32, Alex Shi 写道:
>>
> I have run thpscale with 'always' defrag setting of THP. The Amean stddev is 
> much
> larger than a very little average run time reducing.
> 
> But the left patch 4 could show the cmpxchg retry reduce from thousands to 
> hundreds
> or less.
> 
> Subject: [PATCH v4 4/4] add cmpxchg tracing


It's a typical result with the patchset:

 Performance counter stats for './run-mmtests.sh -c 
configs/config-workload-thpscale pageblock-c':

 9,564  compaction:mm_compaction_isolate_migratepages
 6,430  compaction:mm_compaction_isolate_freepages
 5,287  compaction:mm_compaction_migratepages
45,299  compaction:mm_compaction_begin
45,299  compaction:mm_compaction_end
30,557  compaction:mm_compaction_try_to_compact_pages
95,540  compaction:mm_compaction_finished
   149,379  compaction:mm_compaction_suitable
 0  compaction:mm_compaction_deferred
 0  compaction:mm_compaction_defer_compaction
 3,949  compaction:mm_compaction_defer_reset
 0  compaction:mm_compaction_kcompactd_sleep
 0  compaction:mm_compaction_wakeup_kcompactd
 0  compaction:mm_compaction_kcompactd_wake
68  pageblock:hit_cmpxchg

 113.570974583 seconds time elapsed

  14.664451000 seconds user
  96.847116000 seconds sys

It's 5.9-rc2 base kernel result:

 Performance counter stats for './run-mmtests.sh -c 
configs/config-workload-thpscale rc2-e':

15,920  compaction:mm_compaction_isolate_migratepages
20,523  compaction:mm_compaction_isolate_freepages
 9,752  compaction:mm_compaction_migratepages
27,773  compaction:mm_compaction_begin
27,773  compaction:mm_compaction_end
16,391  compaction:mm_compaction_try_to_compact_pages
62,809  compaction:mm_compaction_finished
69,821  compaction:mm_compaction_suitable
 0  compaction:mm_compaction_deferred
 0  compaction:mm_compaction_defer_compaction
 7,875  compaction:mm_compaction_defer_reset
 0  compaction:mm_compaction_kcompactd_sleep
 0  compaction:mm_compaction_wakeup_kcompactd
 0  compaction:mm_compaction_kcompactd_wake
 1,208  pageblock:hit_cmpxchg

 116.440414591 seconds time elapsed

  15.326913000 seconds user
 103.752758000 seconds sys



Re: [PATCH 22/28] sgiseeq: convert from dma_cache_sync to dma_sync_single_for_device

2020-09-03 Thread Christoph Hellwig
On Wed, Sep 02, 2020 at 11:38:09PM +0200, Thomas Bogendoerfer wrote:
> the patch below fixes the problem.

But is very wrong unfortunately.

>  static inline void dma_sync_desc_cpu(struct net_device *dev, void *addr)
>  {
> -   dma_cache_sync(dev->dev.parent, addr, sizeof(struct sgiseeq_rx_desc),
> -  DMA_FROM_DEVICE);
> +   struct sgiseeq_private *sp = netdev_priv(dev);
> +
> +   dma_sync_single_for_device(dev->dev.parent, VIRT_TO_DMA(sp, addr),
> +   sizeof(struct sgiseeq_rx_desc), DMA_FROM_DEVICE);
>  }
>  
>  static inline void dma_sync_desc_dev(struct net_device *dev, void *addr)
>  {
> -   dma_cache_sync(dev->dev.parent, addr, sizeof(struct sgiseeq_rx_desc),
> -  DMA_TO_DEVICE);
> +   struct sgiseeq_private *sp = netdev_priv(dev);
> +
> +   dma_sync_single_for_device(dev->dev.parent, VIRT_TO_DMA(sp, addr),
> +   sizeof(struct sgiseeq_rx_desc), DMA_TO_DEVICE);

This is not how the DMA API works.  You can only call
dma_sync_single_for_{device,cpu} with the direction that the memory
was mapped.  It then transfer ownership to the device or the cpu,
and the ownership of the memory is a fundamental concept that allows
for reasoning about the caching interaction.

>  }
>  
> -- 
> Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
> good idea.[ RFC1925, 2.3 ]
---end quoted text---


Re: [PATCH 22/28] sgiseeq: convert from dma_cache_sync to dma_sync_single_for_device

2020-09-03 Thread Christoph Hellwig
On Tue, Sep 01, 2020 at 07:38:10PM +0200, Thomas Bogendoerfer wrote:
> this is the problem:
> 
>/* Always check for received packets. */
> sgiseeq_rx(dev, sp, hregs, sregs);
> 
> so the driver will look at the rx descriptor on every interrupt, so
> we cache the rx descriptor on the first interrupt and if there was
> $no rx packet, we will only see it, if cache line gets flushed for
> some other reason.

That means a transfer back to device ownership is missing after a
(negative) check.

> kick_tx() does a busy loop checking tx descriptors,
> with just sync_desc_cpu...
> 
> Thomas.
> 
> -- 
> Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
> good idea.[ RFC1925, 2.3 ]
---end quoted text---


linux-next: Fixes tag needs some work in the mips-fixes tree

2020-09-03 Thread Stephen Rothwell
Hi all,

In commit

  f8a005e1632c ("MIPS: add missing MSACSR and upper MSA initialization")

Fixes tag

  Fixes: cc97ab235f ("MIPS: Simplify FP context initialization")

has these problem(s):

  - SHA1 should be at least 12 digits long
Can be fixed by setting core.abbrev to 12 (or more) or (for git v2.11
or later) just making sure it is not set (or set to "auto").

-- 
Cheers,
Stephen Rothwell


pgp72vN2nFMGH.pgp
Description: OpenPGP digital signature


Re: [Re-send][PATCH] gpu/drm: remove drm_modeset_lock protection for drm_error

2020-09-03 Thread Daniel Vetter
On Wed, Sep 02, 2020 at 09:17:02PM +0800, Bernard wrote:
> In function drm_atomic_helper_shutdown, maybe there is no need
> to protect DRM_ERROR log in DRM_MODESET_LOCK_ALL_BEGIN &
> DRM_MODESET_LOCK_ALL_END. This change is to make code run a bit
> fast.
> 
> Signed-off-by: Bernard Zhao 

This is only run at driver unload, so really no need to optimize anything
for speed. And I think this change makes the code less symmetric, so not
really worth it imo.

Similar with the via change, drm/via is very very legacy code where the
next step will be to just outright delete it all.

Thanks anyway for submitting the patches, in other places such a change
would indeed make sense I think.
-Daniel

> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> b/drivers/gpu/drm/drm_atomic_helper.c
> index 85d163f16801..8902fd6316fc 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -3100,12 +3100,10 @@ void drm_atomic_helper_shutdown(struct drm_device 
> *dev)
>   int ret;
>  
>   DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
> -
>   ret = drm_atomic_helper_disable_all(dev, &ctx);
> + DRM_MODESET_LOCK_ALL_END(ctx, ret);
>   if (ret)
>   DRM_ERROR("Disabling all crtc's during unload failed with 
> %i\n", ret);
> -
> - DRM_MODESET_LOCK_ALL_END(ctx, ret);
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_shutdown);
>  
> -- 
> 2.17.1
> 
> 
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH v2 6/9] spi: spi-s3c64xx: Check return values

2020-09-03 Thread Lukasz Stelmach
It was <2020-09-02 śro 10:14>, when Sylwester Nawrocki wrote:
> On 9/1/20 17:21, Lukasz Stelmach wrote:
>> It was <2020-08-25 wto 21:06>, when Sylwester Nawrocki wrote:
>>> On 8/21/20 18:13, Łukasz Stelmach wrote:
 Check return values in prepare_dma() and s3c64xx_spi_config() and
 propagate errors upwards.

 Signed-off-by: Łukasz Stelmach
 ---
drivers/spi/spi-s3c64xx.c | 47 ---
1 file changed, 39 insertions(+), 8 deletions(-)
>>>
 @@ -298,12 +299,24 @@ static void prepare_dma(struct s3c64xx_spi_dma_data 
 *dma,
desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents,
   dma->direction, 
 DMA_PREP_INTERRUPT);
 +  if (!desc) {
 +  dev_err(&sdd->pdev->dev, "unable to prepare %s scatterlist",
 +  dma->direction == DMA_DEV_TO_MEM ? "rx" : "tx");
 +  return -ENOMEM;
 +  }
desc->callback = s3c64xx_spi_dmacb;
desc->callback_param = dma;
dma->cookie = dmaengine_submit(desc);
 +  ret = dma_submit_error(dma->cookie);
 +  if (ret) {
 +  dev_err(&sdd->pdev->dev, "DMA submission failed");
 +  return -EIO;
>>>
>>> Just return the error value from dma_submit_error() here?
>>>
>>
>> --8<---cut here---start->8---
>> static inline int dma_submit_error(dma_cookie_t cookie)
>> {
>>  return cookie < 0 ? cookie : 0;
>>
>> }
>> --8<---cut here---end--->8---
>>
>> Not quite meaningful IMHO, is it?
>
> dma_submit_error() returns 0 or an error code, I think it makes sense
> to propagate that error code rather than replacing it with -EIO.

It is not an error code that d_s_e() returns it is a value returned by
dma_cookie_assigned() called from within the tx_submit() operaton of a
DMA driver.

--8<---cut here---start->8---
static inline dma_cookie_t dma_cookie_assign(struct
dma_async_tx_descriptor *tx)
{
struct dma_chan *chan = tx->chan;
dma_cookie_t cookie;

cookie = chan->cookie + 1;
if (cookie < DMA_MIN_COOKIE)
cookie = DMA_MIN_COOKIE;
tx->cookie = chan->cookie = cookie;

return cookie;
}
--8<---cut here---end--->8---

Yes, a non-zero value returned by d_s_e() indicates an error but it
definitely isn't one of error codes from errno*.h.

-- 
Łukasz Stelmach
Samsung R&D Institute Poland
Samsung Electronics


signature.asc
Description: PGP signature


Re: [PATCH 22/28] sgiseeq: convert from dma_cache_sync to dma_sync_single_for_device

2020-09-03 Thread Christoph Hellwig
On Thu, Sep 03, 2020 at 10:43:02AM +0200, Christoph Hellwig wrote:
> On Tue, Sep 01, 2020 at 07:38:10PM +0200, Thomas Bogendoerfer wrote:
> > this is the problem:
> > 
> >/* Always check for received packets. */
> > sgiseeq_rx(dev, sp, hregs, sregs);
> > 
> > so the driver will look at the rx descriptor on every interrupt, so
> > we cache the rx descriptor on the first interrupt and if there was
> > $no rx packet, we will only see it, if cache line gets flushed for
> > some other reason.
> 
> That means a transfer back to device ownership is missing after a
> (negative) check.

E.g. something like this for the particular problem, although there
might be other hiding elsewhere:

diff --git a/drivers/net/ethernet/seeq/sgiseeq.c 
b/drivers/net/ethernet/seeq/sgiseeq.c
index 8507ff2420143a..a1c7be8a0d1e5d 100644
--- a/drivers/net/ethernet/seeq/sgiseeq.c
+++ b/drivers/net/ethernet/seeq/sgiseeq.c
@@ -403,6 +403,8 @@ static inline void sgiseeq_rx(struct net_device *dev, 
struct sgiseeq_private *sp
rd = &sp->rx_desc[sp->rx_new];
dma_sync_desc_cpu(dev, rd);
}
+   dma_sync_desc_dev(dev, rd);
+
dma_sync_desc_cpu(dev, &sp->rx_desc[orig_end]);
sp->rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR);
dma_sync_desc_dev(dev, &sp->rx_desc[orig_end]);


linux-next: Fixes tag needs some work in the scsi-fixes tree

2020-09-03 Thread Stephen Rothwell
Hi all,

In commit

  b614d55b970d ("scsi: mpt3sas: Don't call disable_irq from IRQ poll handler")

Fixes tag

  Fixes: 320e77acb3 scsi: mpt3sas: Irq poll to avoid CPU hard lockups

has these problem(s):

  - SHA1 should be at least 12 digits long

In commit

  d2af39141eea ("scsi: megaraid_sas: Don't call disable_irq from process IRQ 
poll")

Fixes tag

  Fixes: a6ffd5bf681 scsi: megaraid_sas: Call disable_irq from process IRQ poll

has these problem(s):

  - SHA1 should be at least 12 digits long

These can be fixed in the future by setting core.abbrev to 12 (or more)
or (for git v2.11 or later) just making sure it is not set (or set to
"auto").

Also, Fixes tags are usually generated using

  git log -1 --format='Fixes: %h ("%s")' 

-- 
Cheers,
Stephen Rothwell


pgpJwFviQ3lx0.pgp
Description: OpenPGP digital signature


[PATCH] mmc: host: omap-hsmmc: remove redundant null check

2020-09-03 Thread Xu Wang
Because clk_disable_unprepare already checked NULL clock
parameter, so the additional checks are unnecessary, just remove them.

Signed-off-by: Xu Wang 
---
 drivers/mmc/host/omap_hsmmc.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 37b8740513f5..d02983e23ed1 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1114,8 +1114,7 @@ static int omap_hsmmc_switch_opcond(struct 
omap_hsmmc_host *host, int vdd)
int ret;
 
/* Disable the clocks */
-   if (host->dbclk)
-   clk_disable_unprepare(host->dbclk);
+   clk_disable_unprepare(host->dbclk);
 
/* Turn the power off */
ret = omap_hsmmc_set_power(host, 0);
@@ -1123,8 +1122,7 @@ static int omap_hsmmc_switch_opcond(struct 
omap_hsmmc_host *host, int vdd)
/* Turn the power ON with given VDD 1.8 or 3.0v */
if (!ret)
ret = omap_hsmmc_set_power(host, 1);
-   if (host->dbclk)
-   clk_prepare_enable(host->dbclk);
+   clk_prepare_enable(host->dbclk);
 
if (ret != 0)
goto err;
@@ -2014,8 +2012,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
pm_runtime_dont_use_autosuspend(host->dev);
pm_runtime_put_sync(host->dev);
pm_runtime_disable(host->dev);
-   if (host->dbclk)
-   clk_disable_unprepare(host->dbclk);
+   clk_disable_unprepare(host->dbclk);
 err1:
mmc_free_host(mmc);
 err:
@@ -2037,8 +2034,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
pm_runtime_put_sync(host->dev);
pm_runtime_disable(host->dev);
device_init_wakeup(&pdev->dev, false);
-   if (host->dbclk)
-   clk_disable_unprepare(host->dbclk);
+   clk_disable_unprepare(host->dbclk);
 
mmc_free_host(host->mmc);
 
@@ -2063,8 +2059,7 @@ static int omap_hsmmc_suspend(struct device *dev)
OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
}
 
-   if (host->dbclk)
-   clk_disable_unprepare(host->dbclk);
+   clk_disable_unprepare(host->dbclk);
 
pm_runtime_put_sync(host->dev);
return 0;
@@ -2080,8 +2075,7 @@ static int omap_hsmmc_resume(struct device *dev)
 
pm_runtime_get_sync(host->dev);
 
-   if (host->dbclk)
-   clk_prepare_enable(host->dbclk);
+   clk_prepare_enable(host->dbclk);
 
if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
omap_hsmmc_conf_bus_power(host);
-- 
2.17.1



<    1   2   3   4   5   6   7   8   9   10   >