mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
* drm/bridge/lontium-lt9611uxc: EDID fixes; Don't handle hotplug
events in IRQ handler * drm/ttm: Use _GFP_NOWARN for huge pages -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmAZRv0ACgkQaA3BHVML eiNFuQgAszjfalGGEY4ekS3iddlIlfB5yaKVjbsJ5YZnI6bcUwcezyBZWM7DK1ba gDQpAP+yQSpscm0jDKMgo0eeRJceZUnwNa18aJgb34VLm8mPlyy5yzQh7IWJZUbS hNvVs6CIpTTcl4+uqftvcKPtB0B/4ftubz5nOItJrM5I7enG+GY5nV0tbaV4ioyS SySkNVIuk+oaoaiPAV5nO2HkbtMq7rap1lBtNqmwUinU/20/GNG4jjv5I6ysEsyE p3wUP4ytiq80tdOMhKvOKG0OQw74Hh5iBmaPLx/CzmWAsWJ95/RLWSINtzXcnci/ c8UTDBPvg2FDYhpqTPmVPyVwOeu8wA== =DvIJ -----END PGP SIGNATURE----- Merge tag 'drm-misc-fixes-2021-02-02' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes * drm/bridge/lontium-lt9611uxc: EDID fixes; Don't handle hotplug events in IRQ handler * drm/ttm: Use _GFP_NOWARN for huge pages Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/YBlHU4sc/5GHpXpg@linux-uq9g
This commit is contained in:
commit
6fc5e3022f
2 changed files with 48 additions and 15 deletions
|
@ -14,6 +14,7 @@
|
|||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <sound/hdmi-codec.h>
|
||||
|
||||
|
@ -36,6 +37,7 @@ struct lt9611uxc {
|
|||
struct mutex ocm_lock;
|
||||
|
||||
struct wait_queue_head wq;
|
||||
struct work_struct work;
|
||||
|
||||
struct device_node *dsi0_node;
|
||||
struct device_node *dsi1_node;
|
||||
|
@ -52,6 +54,8 @@ struct lt9611uxc {
|
|||
|
||||
bool hpd_supported;
|
||||
bool edid_read;
|
||||
/* can be accessed from different threads, so protect this with ocm_lock */
|
||||
bool hdmi_connected;
|
||||
uint8_t fw_version;
|
||||
};
|
||||
|
||||
|
@ -143,21 +147,41 @@ static irqreturn_t lt9611uxc_irq_thread_handler(int irq, void *dev_id)
|
|||
if (irq_status)
|
||||
regmap_write(lt9611uxc->regmap, 0xb022, 0);
|
||||
|
||||
lt9611uxc_unlock(lt9611uxc);
|
||||
|
||||
if (irq_status & BIT(0))
|
||||
if (irq_status & BIT(0)) {
|
||||
lt9611uxc->edid_read = !!(hpd_status & BIT(0));
|
||||
|
||||
if (irq_status & BIT(1)) {
|
||||
if (lt9611uxc->connector.dev)
|
||||
drm_kms_helper_hotplug_event(lt9611uxc->connector.dev);
|
||||
else
|
||||
drm_bridge_hpd_notify(<9611uxc->bridge, !!(hpd_status & BIT(1)));
|
||||
wake_up_all(<9611uxc->wq);
|
||||
}
|
||||
|
||||
if (irq_status & BIT(1)) {
|
||||
lt9611uxc->hdmi_connected = hpd_status & BIT(1);
|
||||
schedule_work(<9611uxc->work);
|
||||
}
|
||||
|
||||
lt9611uxc_unlock(lt9611uxc);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void lt9611uxc_hpd_work(struct work_struct *work)
|
||||
{
|
||||
struct lt9611uxc *lt9611uxc = container_of(work, struct lt9611uxc, work);
|
||||
bool connected;
|
||||
|
||||
if (lt9611uxc->connector.dev)
|
||||
drm_kms_helper_hotplug_event(lt9611uxc->connector.dev);
|
||||
else {
|
||||
|
||||
mutex_lock(<9611uxc->ocm_lock);
|
||||
connected = lt9611uxc->hdmi_connected;
|
||||
mutex_unlock(<9611uxc->ocm_lock);
|
||||
|
||||
drm_bridge_hpd_notify(<9611uxc->bridge,
|
||||
connected ?
|
||||
connector_status_connected :
|
||||
connector_status_disconnected);
|
||||
}
|
||||
}
|
||||
|
||||
static void lt9611uxc_reset(struct lt9611uxc *lt9611uxc)
|
||||
{
|
||||
gpiod_set_value_cansleep(lt9611uxc->reset_gpio, 1);
|
||||
|
@ -445,18 +469,21 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid
|
|||
struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge);
|
||||
unsigned int reg_val = 0;
|
||||
int ret;
|
||||
int connected = 1;
|
||||
bool connected = true;
|
||||
|
||||
lt9611uxc_lock(lt9611uxc);
|
||||
|
||||
if (lt9611uxc->hpd_supported) {
|
||||
lt9611uxc_lock(lt9611uxc);
|
||||
ret = regmap_read(lt9611uxc->regmap, 0xb023, ®_val);
|
||||
lt9611uxc_unlock(lt9611uxc);
|
||||
|
||||
if (ret)
|
||||
dev_err(lt9611uxc->dev, "failed to read hpd status: %d\n", ret);
|
||||
else
|
||||
connected = reg_val & BIT(1);
|
||||
}
|
||||
lt9611uxc->hdmi_connected = connected;
|
||||
|
||||
lt9611uxc_unlock(lt9611uxc);
|
||||
|
||||
return connected ? connector_status_connected :
|
||||
connector_status_disconnected;
|
||||
|
@ -465,7 +492,7 @@ static enum drm_connector_status lt9611uxc_bridge_detect(struct drm_bridge *brid
|
|||
static int lt9611uxc_wait_for_edid(struct lt9611uxc *lt9611uxc)
|
||||
{
|
||||
return wait_event_interruptible_timeout(lt9611uxc->wq, lt9611uxc->edid_read,
|
||||
msecs_to_jiffies(100));
|
||||
msecs_to_jiffies(500));
|
||||
}
|
||||
|
||||
static int lt9611uxc_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
|
||||
|
@ -503,7 +530,10 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge,
|
|||
ret = lt9611uxc_wait_for_edid(lt9611uxc);
|
||||
if (ret < 0) {
|
||||
dev_err(lt9611uxc->dev, "wait for EDID failed: %d\n", ret);
|
||||
return ERR_PTR(ret);
|
||||
return NULL;
|
||||
} else if (ret == 0) {
|
||||
dev_err(lt9611uxc->dev, "wait for EDID timeout\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return drm_do_get_edid(connector, lt9611uxc_get_edid_block, lt9611uxc);
|
||||
|
@ -926,6 +956,8 @@ static int lt9611uxc_probe(struct i2c_client *client,
|
|||
lt9611uxc->fw_version = ret;
|
||||
|
||||
init_waitqueue_head(<9611uxc->wq);
|
||||
INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work);
|
||||
|
||||
ret = devm_request_threaded_irq(dev, client->irq, NULL,
|
||||
lt9611uxc_irq_thread_handler,
|
||||
IRQF_ONESHOT, "lt9611uxc", lt9611uxc);
|
||||
|
@ -962,6 +994,7 @@ static int lt9611uxc_remove(struct i2c_client *client)
|
|||
struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client);
|
||||
|
||||
disable_irq(client->irq);
|
||||
flush_scheduled_work();
|
||||
lt9611uxc_audio_exit(lt9611uxc);
|
||||
drm_bridge_remove(<9611uxc->bridge);
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
|
|||
* put_page() on a TTM allocated page is illegal.
|
||||
*/
|
||||
if (order)
|
||||
gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY |
|
||||
gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN |
|
||||
__GFP_KSWAPD_RECLAIM;
|
||||
|
||||
if (!pool->use_dma_alloc) {
|
||||
|
|
Loading…
Reference in a new issue