usb: isp1760: hcd: refactor mempool config and setup
In preparation to support other family member IP, which may have different memory layout. Drop macros and setup a configuration struct. Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org> Link: https://lore.kernel.org/r/20210513084717.2487366-6-rui.silva@linaro.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
f9a88370e6
commit
a74f639c5b
@ -101,6 +101,25 @@ void isp1760_set_pullup(struct isp1760_device *isp, bool enable)
|
|||||||
isp1760_field_set(udc->fields, HW_DP_PULLUP_CLEAR);
|
isp1760_field_set(udc->fields, HW_DP_PULLUP_CLEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 60kb divided in:
|
||||||
|
* - 32 blocks @ 256 bytes
|
||||||
|
* - 20 blocks @ 1024 bytes
|
||||||
|
* - 4 blocks @ 8192 bytes
|
||||||
|
*/
|
||||||
|
static const struct isp1760_memory_layout isp176x_memory_conf = {
|
||||||
|
.blocks[0] = 32,
|
||||||
|
.blocks_size[0] = 256,
|
||||||
|
.blocks[1] = 20,
|
||||||
|
.blocks_size[1] = 1024,
|
||||||
|
.blocks[2] = 4,
|
||||||
|
.blocks_size[2] = 8192,
|
||||||
|
|
||||||
|
.ptd_num = 32,
|
||||||
|
.payload_blocks = 32 + 20 + 4,
|
||||||
|
.payload_area_size = 0xf000,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct regmap_range isp176x_hc_volatile_ranges[] = {
|
static const struct regmap_range isp176x_hc_volatile_ranges[] = {
|
||||||
regmap_reg_range(ISP176x_HC_USBCMD, ISP176x_HC_ATL_PTD_LASTPTD),
|
regmap_reg_range(ISP176x_HC_USBCMD, ISP176x_HC_ATL_PTD_LASTPTD),
|
||||||
regmap_reg_range(ISP176x_HC_BUFFER_STATUS, ISP176x_HC_MEMORY),
|
regmap_reg_range(ISP176x_HC_BUFFER_STATUS, ISP176x_HC_MEMORY),
|
||||||
@ -302,6 +321,8 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
|
|||||||
udc->fields[i] = f;
|
udc->fields[i] = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hcd->memory_layout = &isp176x_memory_conf;
|
||||||
|
|
||||||
isp1760_init_core(isp);
|
isp1760_init_core(isp);
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_USB_ISP1760_HCD) && !usb_disabled()) {
|
if (IS_ENABLED(CONFIG_USB_ISP1760_HCD) && !usb_disabled()) {
|
||||||
|
@ -358,39 +358,29 @@ static void ptd_write(void __iomem *base, u32 ptd_offset, u32 slot,
|
|||||||
/* memory management of the 60kb on the chip from 0x1000 to 0xffff */
|
/* memory management of the 60kb on the chip from 0x1000 to 0xffff */
|
||||||
static void init_memory(struct isp1760_hcd *priv)
|
static void init_memory(struct isp1760_hcd *priv)
|
||||||
{
|
{
|
||||||
int i, curr;
|
const struct isp1760_memory_layout *mem = priv->memory_layout;
|
||||||
|
int i, j, curr;
|
||||||
u32 payload_addr;
|
u32 payload_addr;
|
||||||
|
|
||||||
payload_addr = PAYLOAD_OFFSET;
|
payload_addr = PAYLOAD_OFFSET;
|
||||||
for (i = 0; i < BLOCK_1_NUM; i++) {
|
|
||||||
priv->memory_pool[i].start = payload_addr;
|
for (i = 0, curr = 0; i < ARRAY_SIZE(mem->blocks); i++) {
|
||||||
priv->memory_pool[i].size = BLOCK_1_SIZE;
|
for (j = 0; j < mem->blocks[i]; j++, curr++) {
|
||||||
priv->memory_pool[i].free = 1;
|
priv->memory_pool[curr + j].start = payload_addr;
|
||||||
payload_addr += priv->memory_pool[i].size;
|
priv->memory_pool[curr + j].size = mem->blocks_size[i];
|
||||||
|
priv->memory_pool[curr + j].free = 1;
|
||||||
|
payload_addr += priv->memory_pool[curr + j].size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curr = i;
|
WARN_ON(payload_addr - priv->memory_pool[0].start >
|
||||||
for (i = 0; i < BLOCK_2_NUM; i++) {
|
mem->payload_area_size);
|
||||||
priv->memory_pool[curr + i].start = payload_addr;
|
|
||||||
priv->memory_pool[curr + i].size = BLOCK_2_SIZE;
|
|
||||||
priv->memory_pool[curr + i].free = 1;
|
|
||||||
payload_addr += priv->memory_pool[curr + i].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
curr = i;
|
|
||||||
for (i = 0; i < BLOCK_3_NUM; i++) {
|
|
||||||
priv->memory_pool[curr + i].start = payload_addr;
|
|
||||||
priv->memory_pool[curr + i].size = BLOCK_3_SIZE;
|
|
||||||
priv->memory_pool[curr + i].free = 1;
|
|
||||||
payload_addr += priv->memory_pool[curr + i].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN_ON(payload_addr - priv->memory_pool[0].start > PAYLOAD_AREA_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
||||||
{
|
{
|
||||||
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
||||||
|
const struct isp1760_memory_layout *mem = priv->memory_layout;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
WARN_ON(qtd->payload_addr);
|
WARN_ON(qtd->payload_addr);
|
||||||
@ -398,7 +388,7 @@ static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
|||||||
if (!qtd->length)
|
if (!qtd->length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < BLOCKS; i++) {
|
for (i = 0; i < mem->payload_blocks; i++) {
|
||||||
if (priv->memory_pool[i].size >= qtd->length &&
|
if (priv->memory_pool[i].size >= qtd->length &&
|
||||||
priv->memory_pool[i].free) {
|
priv->memory_pool[i].free) {
|
||||||
priv->memory_pool[i].free = 0;
|
priv->memory_pool[i].free = 0;
|
||||||
@ -411,12 +401,13 @@ static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
|||||||
static void free_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
static void free_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
||||||
{
|
{
|
||||||
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
||||||
|
const struct isp1760_memory_layout *mem = priv->memory_layout;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!qtd->payload_addr)
|
if (!qtd->payload_addr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < BLOCKS; i++) {
|
for (i = 0; i < mem->payload_blocks; i++) {
|
||||||
if (priv->memory_pool[i].start == qtd->payload_addr) {
|
if (priv->memory_pool[i].start == qtd->payload_addr) {
|
||||||
WARN_ON(priv->memory_pool[i].free);
|
WARN_ON(priv->memory_pool[i].free);
|
||||||
priv->memory_pool[i].free = 1;
|
priv->memory_pool[i].free = 1;
|
||||||
@ -1407,8 +1398,6 @@ static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len)
|
|||||||
{
|
{
|
||||||
qtd->data_buffer = databuffer;
|
qtd->data_buffer = databuffer;
|
||||||
|
|
||||||
if (len > MAX_PAYLOAD_SIZE)
|
|
||||||
len = MAX_PAYLOAD_SIZE;
|
|
||||||
qtd->length = len;
|
qtd->length = len;
|
||||||
|
|
||||||
return qtd->length;
|
return qtd->length;
|
||||||
@ -1432,6 +1421,8 @@ static void qtd_list_free(struct list_head *qtd_list)
|
|||||||
static void packetize_urb(struct usb_hcd *hcd,
|
static void packetize_urb(struct usb_hcd *hcd,
|
||||||
struct urb *urb, struct list_head *head, gfp_t flags)
|
struct urb *urb, struct list_head *head, gfp_t flags)
|
||||||
{
|
{
|
||||||
|
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
||||||
|
const struct isp1760_memory_layout *mem = priv->memory_layout;
|
||||||
struct isp1760_qtd *qtd;
|
struct isp1760_qtd *qtd;
|
||||||
void *buf;
|
void *buf;
|
||||||
int len, maxpacketsize;
|
int len, maxpacketsize;
|
||||||
@ -1484,6 +1475,10 @@ static void packetize_urb(struct usb_hcd *hcd,
|
|||||||
qtd = qtd_alloc(flags, urb, packet_type);
|
qtd = qtd_alloc(flags, urb, packet_type);
|
||||||
if (!qtd)
|
if (!qtd)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (len > mem->blocks_size[ISP176x_BLOCK_NUM - 1])
|
||||||
|
len = mem->blocks_size[ISP176x_BLOCK_NUM - 1];
|
||||||
|
|
||||||
this_qtd_len = qtd_fill(qtd, buf, len);
|
this_qtd_len = qtd_fill(qtd, buf, len);
|
||||||
list_add_tail(&qtd->qtd_list, head);
|
list_add_tail(&qtd->qtd_list, head);
|
||||||
|
|
||||||
@ -2212,6 +2207,7 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, struct resource *mem,
|
|||||||
int irq, unsigned long irqflags,
|
int irq, unsigned long irqflags,
|
||||||
struct device *dev)
|
struct device *dev)
|
||||||
{
|
{
|
||||||
|
const struct isp1760_memory_layout *mem_layout = priv->memory_layout;
|
||||||
struct usb_hcd *hcd;
|
struct usb_hcd *hcd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -2223,6 +2219,28 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, struct resource *mem,
|
|||||||
|
|
||||||
priv->hcd = hcd;
|
priv->hcd = hcd;
|
||||||
|
|
||||||
|
priv->memory_pool = kcalloc(mem_layout->payload_blocks,
|
||||||
|
sizeof(struct isp1760_memory_chunk),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!priv->memory_pool) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto put_hcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->atl_slots = kcalloc(mem_layout->ptd_num,
|
||||||
|
sizeof(struct isp1760_slotinfo), GFP_KERNEL);
|
||||||
|
if (!priv->atl_slots) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto free_mem_pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->int_slots = kcalloc(mem_layout->ptd_num,
|
||||||
|
sizeof(struct isp1760_slotinfo), GFP_KERNEL);
|
||||||
|
if (!priv->int_slots) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto free_atl_slots;
|
||||||
|
}
|
||||||
|
|
||||||
init_memory(priv);
|
init_memory(priv);
|
||||||
|
|
||||||
hcd->irq = irq;
|
hcd->irq = irq;
|
||||||
@ -2234,13 +2252,19 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, struct resource *mem,
|
|||||||
|
|
||||||
ret = usb_add_hcd(hcd, irq, irqflags);
|
ret = usb_add_hcd(hcd, irq, irqflags);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto free_int_slots;
|
||||||
|
|
||||||
device_wakeup_enable(hcd->self.controller);
|
device_wakeup_enable(hcd->self.controller);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
free_int_slots:
|
||||||
|
kfree(priv->int_slots);
|
||||||
|
free_atl_slots:
|
||||||
|
kfree(priv->atl_slots);
|
||||||
|
free_mem_pool:
|
||||||
|
kfree(priv->memory_pool);
|
||||||
|
put_hcd:
|
||||||
usb_put_hcd(hcd);
|
usb_put_hcd(hcd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2252,4 +2276,7 @@ void isp1760_hcd_unregister(struct isp1760_hcd *priv)
|
|||||||
|
|
||||||
usb_remove_hcd(priv->hcd);
|
usb_remove_hcd(priv->hcd);
|
||||||
usb_put_hcd(priv->hcd);
|
usb_put_hcd(priv->hcd);
|
||||||
|
kfree(priv->atl_slots);
|
||||||
|
kfree(priv->int_slots);
|
||||||
|
kfree(priv->memory_pool);
|
||||||
}
|
}
|
||||||
|
@ -12,24 +12,6 @@ struct isp1760_qtd;
|
|||||||
struct resource;
|
struct resource;
|
||||||
struct usb_hcd;
|
struct usb_hcd;
|
||||||
|
|
||||||
/*
|
|
||||||
* 60kb divided in:
|
|
||||||
* - 32 blocks @ 256 bytes
|
|
||||||
* - 20 blocks @ 1024 bytes
|
|
||||||
* - 4 blocks @ 8192 bytes
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BLOCK_1_NUM 32
|
|
||||||
#define BLOCK_2_NUM 20
|
|
||||||
#define BLOCK_3_NUM 4
|
|
||||||
|
|
||||||
#define BLOCK_1_SIZE 256
|
|
||||||
#define BLOCK_2_SIZE 1024
|
|
||||||
#define BLOCK_3_SIZE 8192
|
|
||||||
#define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM)
|
|
||||||
#define MAX_PAYLOAD_SIZE BLOCK_3_SIZE
|
|
||||||
#define PAYLOAD_AREA_SIZE 0xf000
|
|
||||||
|
|
||||||
struct isp1760_slotinfo {
|
struct isp1760_slotinfo {
|
||||||
struct isp1760_qh *qh;
|
struct isp1760_qh *qh;
|
||||||
struct isp1760_qtd *qtd;
|
struct isp1760_qtd *qtd;
|
||||||
@ -37,6 +19,17 @@ struct isp1760_slotinfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* chip memory management */
|
/* chip memory management */
|
||||||
|
#define ISP176x_BLOCK_NUM 3
|
||||||
|
|
||||||
|
struct isp1760_memory_layout {
|
||||||
|
unsigned int blocks[ISP176x_BLOCK_NUM];
|
||||||
|
unsigned int blocks_size[ISP176x_BLOCK_NUM];
|
||||||
|
|
||||||
|
unsigned int ptd_num;
|
||||||
|
unsigned int payload_blocks;
|
||||||
|
unsigned int payload_area_size;
|
||||||
|
};
|
||||||
|
|
||||||
struct isp1760_memory_chunk {
|
struct isp1760_memory_chunk {
|
||||||
unsigned int start;
|
unsigned int start;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
@ -58,12 +51,14 @@ struct isp1760_hcd {
|
|||||||
struct regmap *regs;
|
struct regmap *regs;
|
||||||
struct regmap_field *fields[HC_FIELD_MAX];
|
struct regmap_field *fields[HC_FIELD_MAX];
|
||||||
|
|
||||||
|
const struct isp1760_memory_layout *memory_layout;
|
||||||
|
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct isp1760_slotinfo atl_slots[32];
|
struct isp1760_slotinfo *atl_slots;
|
||||||
int atl_done_map;
|
int atl_done_map;
|
||||||
struct isp1760_slotinfo int_slots[32];
|
struct isp1760_slotinfo *int_slots;
|
||||||
int int_done_map;
|
int int_done_map;
|
||||||
struct isp1760_memory_chunk memory_pool[BLOCKS];
|
struct isp1760_memory_chunk *memory_pool;
|
||||||
struct list_head qh_list[QH_END];
|
struct list_head qh_list[QH_END];
|
||||||
|
|
||||||
/* periodic schedule support */
|
/* periodic schedule support */
|
||||||
|
Loading…
Reference in New Issue
Block a user